mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
build: centralize the pinned opencode version (#1075)
Keep OpenCode version selection predictable by reading a single repo-wide constant and packaging that pin into orchestrator builds. Remove env and latest-release fallbacks so desktop, workers, snapshots, and CI stay aligned. Co-authored-by: Omar McAdam <omar@OpenWork-Studio.localdomain>
This commit is contained in:
68
.github/workflows/alpha-macos-aarch64.yml
vendored
68
.github/workflows/alpha-macos-aarch64.yml
vendored
@@ -21,7 +21,6 @@ jobs:
|
||||
|
||||
env:
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -85,80 +84,27 @@ jobs:
|
||||
- name: Resolve OpenCode version
|
||||
id: opencode-version
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
node <<'NODE' >> "$GITHUB_OUTPUT"
|
||||
const fs = require('fs');
|
||||
const repo = (process.env.OPENCODE_GITHUB_REPO || 'anomalyco/opencode').trim() || 'anomalyco/opencode';
|
||||
|
||||
async function resolveLatest() {
|
||||
const token = (process.env.GITHUB_TOKEN || '').trim();
|
||||
const headers = {
|
||||
Accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
'User-Agent': 'openwork-ci',
|
||||
};
|
||||
if (token) headers.Authorization = `Bearer ${token}`;
|
||||
|
||||
try {
|
||||
const res = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, { headers });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const tag = (typeof data.tag_name === 'string' ? data.tag_name : '').trim();
|
||||
const version = (tag.startsWith('v') ? tag.slice(1) : tag).trim();
|
||||
if (version) return version;
|
||||
}
|
||||
if (res.status !== 403) {
|
||||
throw new Error(`Failed to resolve latest OpenCode version (HTTP ${res.status})`);
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
|
||||
const web = await fetch(`https://github.com/${repo}/releases/latest`, {
|
||||
headers: { 'User-Agent': 'openwork-ci' },
|
||||
redirect: 'follow',
|
||||
});
|
||||
const url = web && web.url ? String(web.url) : '';
|
||||
const match = url.match(/\/tag\/v([^/?#]+)/);
|
||||
if (!match) throw new Error('Failed to resolve latest OpenCode version (web redirect).');
|
||||
return match[1];
|
||||
const parsed = JSON.parse(fs.readFileSync('./constants.json', 'utf8'));
|
||||
const version = String(parsed.opencodeVersion || '').replace(/^v/, '').trim();
|
||||
if (!version) {
|
||||
throw new Error('Pinned OpenCode version is missing from constants.json');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const pkg = JSON.parse(fs.readFileSync('./apps/desktop/package.json', 'utf8'));
|
||||
const configuredRaw = (process.env.OPENCODE_VERSION || pkg.opencodeVersion || '').toString().trim();
|
||||
if (configuredRaw && configuredRaw.toLowerCase() !== 'latest') {
|
||||
const resolved = (configuredRaw.startsWith('v') ? configuredRaw.slice(1) : configuredRaw).trim();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${resolved}\n`);
|
||||
}
|
||||
console.log('version=' + resolved);
|
||||
return;
|
||||
}
|
||||
const latest = await resolveLatest();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${latest}\n`);
|
||||
}
|
||||
console.log('version=' + latest);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
console.log('version=' + version);
|
||||
NODE
|
||||
|
||||
- name: Download OpenCode sidecar
|
||||
shell: bash
|
||||
env:
|
||||
OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
PINNED_OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}"
|
||||
opencode_asset="opencode-darwin-arm64.zip"
|
||||
url="https://github.com/${repo}/releases/download/v${OPENCODE_VERSION}/${opencode_asset}"
|
||||
url="https://github.com/${repo}/releases/download/v${PINNED_OPENCODE_VERSION}/${opencode_asset}"
|
||||
tmp_dir="$RUNNER_TEMP/opencode"
|
||||
extract_dir="$tmp_dir/extracted"
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
31
.github/workflows/build-desktop.yml
vendored
31
.github/workflows/build-desktop.yml
vendored
@@ -71,45 +71,18 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}"
|
||||
version="${OPENCODE_VERSION:-}"
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
version="$(node -p "require('./apps/desktop/package.json').opencodeVersion || ''" 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
version="$(node -e "const fs=require('fs'); const parsed=JSON.parse(fs.readFileSync('constants.json','utf8')); process.stdout.write(String(parsed.opencodeVersion||'').trim().replace(/^v/,''));")"
|
||||
version="$(echo "$version" | tr -d '\r\n' | sed 's/^v//')"
|
||||
if [ -z "$version" ] || [ "$version" = "latest" ]; then
|
||||
latest=""
|
||||
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||
latest=$(curl -fsSL \
|
||||
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"https://api.github.com/repos/${repo}/releases/latest" \
|
||||
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
|
||||
else
|
||||
latest=$(curl -fsSL \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"https://api.github.com/repos/${repo}/releases/latest" \
|
||||
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
|
||||
fi
|
||||
if [ -n "$latest" ]; then
|
||||
version="$latest"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
echo "Unable to resolve OpenCode version (set OPENCODE_VERSION to pin)." >&2
|
||||
echo "Unable to resolve OpenCode version from constants.json." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Reuse this resolved version for subsequent steps (e.g. prepare-sidecar).
|
||||
echo "OPENCODE_VERSION=$version" >> "$GITHUB_ENV"
|
||||
|
||||
opencode_asset="opencode-linux-x64-baseline.tar.gz"
|
||||
url="https://github.com/${repo}/releases/download/v${version}/${opencode_asset}"
|
||||
tmp_dir="$RUNNER_TEMP/opencode"
|
||||
|
||||
29
.github/workflows/ci-tests.yml
vendored
29
.github/workflows/ci-tests.yml
vendored
@@ -39,40 +39,15 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}"
|
||||
version="${OPENCODE_VERSION:-}"
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
version="$(node -p "require('./apps/desktop/package.json').opencodeVersion || ''" 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
version="$(node -e "const fs=require('fs'); const parsed=JSON.parse(fs.readFileSync('constants.json','utf8')); process.stdout.write(String(parsed.opencodeVersion||'').trim().replace(/^v/,''));")"
|
||||
version="$(echo "$version" | tr -d '\r\n' | sed 's/^v//')"
|
||||
|
||||
if [ -z "$version" ] || [ "$version" = "latest" ]; then
|
||||
latest=""
|
||||
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||
latest=$(curl -fsSL \
|
||||
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"https://api.github.com/repos/${repo}/releases/latest" \
|
||||
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
|
||||
else
|
||||
latest=$(curl -fsSL \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"https://api.github.com/repos/${repo}/releases/latest" \
|
||||
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
|
||||
fi
|
||||
if [ -n "$latest" ]; then
|
||||
version="$latest"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
echo "Unable to resolve OpenCode version (set OPENCODE_VERSION to pin)." >&2
|
||||
echo "Unable to resolve OpenCode version from constants.json." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
8
.github/workflows/opencode-agents.yml
vendored
8
.github/workflows/opencode-agents.yml
vendored
@@ -20,7 +20,9 @@ jobs:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install opencode
|
||||
run: curl -fsSL https://opencode.ai/install | bash
|
||||
run: |
|
||||
version="$(node -e "const fs=require('fs'); const parsed=JSON.parse(fs.readFileSync('constants.json','utf8')); process.stdout.write(String(parsed.opencodeVersion||'').trim().replace(/^v/,''));")"
|
||||
curl -fsSL https://opencode.ai/install | bash -s -- --version "$version" --no-modify-path
|
||||
|
||||
- name: Triage issue
|
||||
env:
|
||||
@@ -48,7 +50,9 @@ jobs:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install opencode
|
||||
run: curl -fsSL https://opencode.ai/install | bash
|
||||
run: |
|
||||
version="$(node -e "const fs=require('fs'); const parsed=JSON.parse(fs.readFileSync('constants.json','utf8')); process.stdout.write(String(parsed.opencodeVersion||'').trim().replace(/^v/,''));")"
|
||||
curl -fsSL https://opencode.ai/install | bash -s -- --version "$version" --no-modify-path
|
||||
|
||||
- name: Build prompt
|
||||
env:
|
||||
|
||||
72
.github/workflows/prerelease.yml
vendored
72
.github/workflows/prerelease.yml
vendored
@@ -85,7 +85,6 @@ jobs:
|
||||
RELEASE_BODY: ${{ needs.prepare-release.outputs.release_body }}
|
||||
MACOS_NOTARIZE: ${{ vars.MACOS_NOTARIZE || 'false' }}
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -172,78 +171,21 @@ jobs:
|
||||
- name: Resolve OpenCode version
|
||||
id: opencode-version
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
node <<'NODE' >> "$GITHUB_OUTPUT"
|
||||
const fs = require('fs');
|
||||
const repo = (process.env.OPENCODE_GITHUB_REPO || 'anomalyco/opencode').trim() || 'anomalyco/opencode';
|
||||
|
||||
async function resolveLatest() {
|
||||
const token = (process.env.GITHUB_TOKEN || '').trim();
|
||||
const headers = {
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
'User-Agent': 'openwork-ci',
|
||||
};
|
||||
if (token) headers.Authorization = `Bearer ${token}`;
|
||||
|
||||
// Prefer API, but fall back to the web "latest" redirect if rate-limited (403) or otherwise blocked.
|
||||
try {
|
||||
const res = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, { headers });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const tag = (typeof data.tag_name === 'string' ? data.tag_name : '').trim();
|
||||
let v = tag.startsWith('v') ? tag.slice(1) : tag;
|
||||
v = v.trim();
|
||||
if (v) return v;
|
||||
}
|
||||
if (res.status !== 403) {
|
||||
throw new Error(`Failed to resolve latest OpenCode version (HTTP ${res.status})`);
|
||||
}
|
||||
} catch {
|
||||
// continue to fallback
|
||||
}
|
||||
|
||||
const web = await fetch(`https://github.com/${repo}/releases/latest`, {
|
||||
headers: { 'User-Agent': 'openwork-ci' },
|
||||
redirect: 'follow',
|
||||
});
|
||||
const url = (web && web.url) ? String(web.url) : '';
|
||||
const match = url.match(/\/tag\/v([^/?#]+)/);
|
||||
if (!match) throw new Error('Failed to resolve latest OpenCode version (web redirect).');
|
||||
return match[1];
|
||||
const parsed = JSON.parse(fs.readFileSync('./constants.json', 'utf8'));
|
||||
const version = String(parsed.opencodeVersion || '').replace(/^v/, '').trim();
|
||||
if (!version) {
|
||||
throw new Error('Pinned OpenCode version is missing from constants.json');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const pkg = JSON.parse(fs.readFileSync('./apps/desktop/package.json', 'utf8'));
|
||||
const configuredRaw = (process.env.OPENCODE_VERSION || pkg.opencodeVersion || '').toString().trim();
|
||||
if (configuredRaw && configuredRaw.toLowerCase() !== 'latest') {
|
||||
const normalized = configuredRaw.startsWith('v') ? configuredRaw.slice(1) : configuredRaw;
|
||||
const resolved = normalized.trim();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${resolved}\n`);
|
||||
}
|
||||
console.log('version=' + resolved);
|
||||
return;
|
||||
}
|
||||
const latest = await resolveLatest();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${latest}\n`);
|
||||
}
|
||||
console.log('version=' + latest);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
console.log('version=' + version);
|
||||
NODE
|
||||
|
||||
- name: Download OpenCode sidecar
|
||||
shell: bash
|
||||
env:
|
||||
OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
PINNED_OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -270,7 +212,7 @@ jobs:
|
||||
esac
|
||||
|
||||
repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}"
|
||||
url="https://github.com/${repo}/releases/download/v${OPENCODE_VERSION}/${opencode_asset}"
|
||||
url="https://github.com/${repo}/releases/download/v${PINNED_OPENCODE_VERSION}/${opencode_asset}"
|
||||
tmp_dir="$RUNNER_TEMP/opencode"
|
||||
extract_dir="$tmp_dir/extracted"
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
74
.github/workflows/release-macos-aarch64.yml
vendored
74
.github/workflows/release-macos-aarch64.yml
vendored
@@ -254,7 +254,6 @@ jobs:
|
||||
MACOS_NOTARIZE: ${{ needs.resolve-release.outputs.notarize }}
|
||||
# Ensure Tauri's beforeBuildCommand (prepare:sidecar) uses our fork.
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -373,80 +372,21 @@ jobs:
|
||||
- name: Resolve OpenCode version
|
||||
id: opencode-version
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
OPENCODE_VERSION: ${{ vars.OPENCODE_VERSION || '1.2.20' }}
|
||||
run: |
|
||||
node <<'NODE' >> "$GITHUB_OUTPUT"
|
||||
const fs = require('fs');
|
||||
const repo = (process.env.OPENCODE_GITHUB_REPO || 'anomalyco/opencode').trim() || 'anomalyco/opencode';
|
||||
|
||||
async function resolveLatest() {
|
||||
const token = (process.env.GITHUB_TOKEN || '').trim();
|
||||
const headers = {
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
'User-Agent': 'openwork-ci',
|
||||
};
|
||||
if (token) headers.Authorization = `Bearer ${token}`;
|
||||
|
||||
// Prefer API, but fall back to the web "latest" redirect if rate-limited (403) or otherwise blocked.
|
||||
try {
|
||||
const res = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, { headers });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const tag = (typeof data.tag_name === 'string' ? data.tag_name : '').trim();
|
||||
let v = tag.startsWith('v') ? tag.slice(1) : tag;
|
||||
v = v.trim();
|
||||
if (v) return v;
|
||||
}
|
||||
if (res.status !== 403) {
|
||||
throw new Error(`Failed to resolve latest OpenCode version (HTTP ${res.status})`);
|
||||
}
|
||||
} catch {
|
||||
// continue to fallback
|
||||
}
|
||||
|
||||
const web = await fetch(`https://github.com/${repo}/releases/latest`, {
|
||||
headers: { 'User-Agent': 'openwork-ci' },
|
||||
redirect: 'follow',
|
||||
});
|
||||
const url = (web && web.url) ? String(web.url) : '';
|
||||
const match = url.match(/\/tag\/v([^/?#]+)/);
|
||||
if (!match) throw new Error('Failed to resolve latest OpenCode version (web redirect).');
|
||||
return match[1];
|
||||
const parsed = JSON.parse(fs.readFileSync('./constants.json', 'utf8'));
|
||||
const version = String(parsed.opencodeVersion || '').replace(/^v/, '').trim();
|
||||
if (!version) {
|
||||
throw new Error('Pinned OpenCode version is missing from constants.json');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const pkg = JSON.parse(fs.readFileSync('./apps/desktop/package.json', 'utf8'));
|
||||
const configuredRaw = (process.env.OPENCODE_VERSION || pkg.opencodeVersion || '').toString().trim();
|
||||
if (configuredRaw && configuredRaw.toLowerCase() !== 'latest') {
|
||||
const normalized = configuredRaw.startsWith('v') ? configuredRaw.slice(1) : configuredRaw;
|
||||
const resolved = normalized.trim();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${resolved}\n`);
|
||||
}
|
||||
console.log('version=' + resolved);
|
||||
return;
|
||||
}
|
||||
const latest = await resolveLatest();
|
||||
if (process.env.GITHUB_ENV) {
|
||||
fs.appendFileSync(process.env.GITHUB_ENV, `OPENCODE_VERSION=${latest}\n`);
|
||||
}
|
||||
console.log('version=' + latest);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
console.log('version=' + version);
|
||||
NODE
|
||||
|
||||
- name: Download OpenCode sidecar
|
||||
shell: bash
|
||||
env:
|
||||
OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
PINNED_OPENCODE_VERSION: ${{ steps.opencode-version.outputs.version }}
|
||||
OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -474,7 +414,7 @@ jobs:
|
||||
esac
|
||||
|
||||
repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}"
|
||||
url="https://github.com/${repo}/releases/download/v${OPENCODE_VERSION}/${opencode_asset}"
|
||||
url="https://github.com/${repo}/releases/download/v${PINNED_OPENCODE_VERSION}/${opencode_asset}"
|
||||
tmp_dir="$RUNNER_TEMP/opencode"
|
||||
extract_dir="$tmp_dir/extracted"
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
Reference in New Issue
Block a user