Skip to content

Commit fa6eb14

Browse files
suibianwanwancz-cli
andcommitted
ci(release): use release assets for publish jobs
Co-Authored-By: cz-cli <noreply@clickzetta.com>
1 parent 9770a66 commit fa6eb14

3 files changed

Lines changed: 116 additions & 23 deletions

File tree

.github/workflows/release-cos.yml

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ jobs:
5252
5353
create-release:
5454
needs: resolve-release
55-
if: needs.resolve-release.outputs.is_stable == 'true'
5655
runs-on: ubuntu-latest
5756
steps:
5857
- uses: actions/checkout@v4
@@ -90,9 +89,14 @@ jobs:
9089
gh release delete "${{ needs.resolve-release.outputs.tag }}" \
9190
--yes --cleanup-tag=false \
9291
--repo "${{ github.repository }}" 2>/dev/null || true
92+
PRERELEASE_ARGS=()
93+
if [ "${{ needs.resolve-release.outputs.is_dev }}" = "true" ]; then
94+
PRERELEASE_ARGS+=(--prerelease)
95+
fi
9396
gh release create "${{ needs.resolve-release.outputs.tag }}" \
9497
--title "${{ needs.resolve-release.outputs.tag }}" \
9598
--notes-file /tmp/release-notes.md \
99+
"${PRERELEASE_ARGS[@]}" \
96100
--repo "${{ github.repository }}"
97101
98102
build:
@@ -206,21 +210,12 @@ jobs:
206210
OPENCODE_VERSION: ${{ needs.resolve-release.outputs.version }}
207211
OPENCODE_ARCHIVE: "1"
208212
OPENCODE_HOST_ONLY: "1"
209-
OPENCODE_RELEASE: ${{ needs.resolve-release.outputs.is_stable == 'true' && '1' || '' }}
213+
OPENCODE_RELEASE: "1"
210214
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
211215
CLICKZETTA_OTEL_ENDPOINT: ${{ secrets.CLICKZETTA_OTEL_ENDPOINT }}
212216
CLICKZETTA_OTEL_HEADERS: ${{ secrets.CLICKZETTA_OTEL_HEADERS }}
213217
run: cd packages/opencode && bun run script/build.ts
214218

215-
- name: Upload build artifacts
216-
uses: actions/upload-artifact@v4
217-
with:
218-
name: release-dist-${{ matrix.os }}-${{ matrix.runner }}-${{ github.run_attempt }}
219-
retention-days: 7
220-
if-no-files-found: error
221-
path: |
222-
packages/opencode/dist/cz-cli-*
223-
224219
upload-installer:
225220
needs: [resolve-release, build]
226221
if: needs.resolve-release.outputs.is_stable == 'true'
@@ -251,12 +246,16 @@ jobs:
251246
node-version: "20"
252247
registry-url: "https://registry.npmjs.org"
253248

254-
- name: Download build artifacts
255-
uses: actions/download-artifact@v4
256-
with:
257-
pattern: release-dist-*-${{ github.run_attempt }}
258-
path: artifacts
259-
merge-multiple: true
249+
- name: Download release assets
250+
env:
251+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
252+
run: |
253+
mkdir -p release-assets artifacts
254+
gh release download "${{ needs.resolve-release.outputs.tag }}" \
255+
--pattern "cz-cli-*" \
256+
--dir release-assets \
257+
--repo "${{ github.repository }}"
258+
node scripts/prepare-release-assets.mjs release-assets artifacts
260259
261260
- name: Publish to npm
262261
env:
@@ -297,12 +296,16 @@ jobs:
297296
HUSKY: "0"
298297
run: bun install --frozen-lockfile
299298

300-
- name: Download build artifacts
301-
uses: actions/download-artifact@v4
302-
with:
303-
pattern: release-dist-*-${{ github.run_attempt }}
304-
path: packages/opencode/dist
305-
merge-multiple: true
299+
- name: Download release assets
300+
env:
301+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
302+
run: |
303+
mkdir -p release-assets
304+
gh release download "${{ needs.resolve-release.outputs.tag }}" \
305+
--pattern "cz-cli-*" \
306+
--dir release-assets \
307+
--repo "${{ github.repository }}"
308+
node scripts/prepare-release-assets.mjs release-assets packages/opencode/dist
306309
307310
- name: Publish to COS
308311
env:
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { describe, expect, test } from "bun:test"
2+
import { execFileSync } from "node:child_process"
3+
import fs from "node:fs"
4+
import os from "node:os"
5+
import path from "node:path"
6+
7+
const repoRoot = path.resolve(import.meta.dirname, "../../..")
8+
9+
describe("prepare release assets", () => {
10+
test("extracts GitHub release archives into dist directories", () => {
11+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "cz-release-assets-"))
12+
const assetsDir = path.join(tmp, "assets")
13+
const distDir = path.join(tmp, "dist")
14+
fs.mkdirSync(path.join(tmp, "darwin-bin"), { recursive: true })
15+
fs.mkdirSync(path.join(tmp, "linux-bin"), { recursive: true })
16+
fs.mkdirSync(path.join(tmp, "windows-bin"), { recursive: true })
17+
fs.writeFileSync(path.join(tmp, "darwin-bin", "cz-cli"), "darwin")
18+
fs.writeFileSync(path.join(tmp, "linux-bin", "cz-cli"), "linux")
19+
fs.writeFileSync(path.join(tmp, "windows-bin", "cz-cli.exe"), "windows")
20+
fs.mkdirSync(assetsDir)
21+
22+
try {
23+
execFileSync("zip", ["-rq", path.join(assetsDir, "cz-cli-darwin-arm64.zip"), "."], {
24+
cwd: path.join(tmp, "darwin-bin"),
25+
})
26+
execFileSync("tar", ["-czf", path.join(assetsDir, "cz-cli-linux-x64.tar.gz"), "."], {
27+
cwd: path.join(tmp, "linux-bin"),
28+
})
29+
execFileSync("zip", ["-rq", path.join(assetsDir, "cz-cli-windows-x64.zip"), "."], {
30+
cwd: path.join(tmp, "windows-bin"),
31+
})
32+
fs.writeFileSync(path.join(assetsDir, "cz-cli-checksums.txt"), "ignored")
33+
34+
execFileSync(
35+
process.execPath,
36+
["run", path.join(repoRoot, "scripts", "prepare-release-assets.mjs"), assetsDir, distDir],
37+
{ cwd: repoRoot },
38+
)
39+
40+
expect(fs.readFileSync(path.join(distDir, "cz-cli-darwin-arm64", "bin", "cz-cli"), "utf8")).toBe("darwin")
41+
expect(fs.readFileSync(path.join(distDir, "cz-cli-linux-x64", "bin", "cz-cli"), "utf8")).toBe("linux")
42+
expect(fs.readFileSync(path.join(distDir, "cz-cli-windows-x64", "bin", "cz-cli.exe"), "utf8")).toBe("windows")
43+
expect(fs.existsSync(path.join(distDir, "cz-cli-checksums.txt"))).toBe(false)
44+
} finally {
45+
fs.rmSync(tmp, { recursive: true, force: true })
46+
}
47+
})
48+
})

scripts/prepare-release-assets.mjs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env node
2+
3+
import { execFileSync } from "node:child_process"
4+
import fs from "node:fs"
5+
import path from "node:path"
6+
7+
const assetsDir = process.argv[2]
8+
const distDir = process.argv[3]
9+
10+
if (!assetsDir || !distDir) {
11+
throw new Error("Usage: prepare-release-assets.mjs <assets-dir> <dist-dir>")
12+
}
13+
14+
if (!fs.existsSync(assetsDir)) {
15+
throw new Error(`assets dir not found: ${assetsDir}`)
16+
}
17+
18+
fs.rmSync(distDir, { recursive: true, force: true })
19+
fs.mkdirSync(distDir, { recursive: true })
20+
21+
const archives = fs
22+
.readdirSync(assetsDir)
23+
.filter((name) => name.startsWith("cz-cli-") && (name.endsWith(".zip") || name.endsWith(".tar.gz")))
24+
25+
if (archives.length === 0) {
26+
throw new Error(`no cz-cli release archives found in ${assetsDir}`)
27+
}
28+
29+
for (const archive of archives) {
30+
const platform = archive.replace(/^cz-cli-/, "").replace(/\.tar\.gz$|\.zip$/, "")
31+
const binDir = path.join(distDir, `cz-cli-${platform}`, "bin")
32+
fs.mkdirSync(binDir, { recursive: true })
33+
34+
if (archive.endsWith(".zip")) {
35+
execFileSync("unzip", ["-q", "-o", path.join(assetsDir, archive), "-d", binDir], { stdio: "inherit" })
36+
continue
37+
}
38+
39+
execFileSync("tar", ["-xzf", path.join(assetsDir, archive), "-C", binDir], { stdio: "inherit" })
40+
}
41+
42+
console.log(`Prepared ${archives.length} release assets in ${distDir}`)

0 commit comments

Comments
 (0)