From 0f3e8629c32b849291416411867141ded7bcaee0 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 10:25:29 +0000 Subject: ci(nightly): publish latest-named assets and version.json Co-Authored-By: Claude Opus 5.5 --- .github/workflows/nightly-build.yml | 44 +++++++++++++++++++++++++++++++++++-- AGENTS/ARCH/NIGHTLY.md | 12 +++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index a9e294b..70e8d41 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -549,7 +549,7 @@ jobs: linux=(release-packages/nightly-linux/cpsc-*-Linux-x86_64.tar.xz) macos=(release-packages/nightly-macos/cpsc-*-Darwin-arm64.tar.xz) windows=(release-packages/nightly-windows/cpsc-*-Windows-*.zip) - plugin=(release-packages/nightly-plugin/*.vsix) + plugin=(release-packages/nightly-plugin/cpsc-plugin-*.vsix) bundle_macos=(release-packages/nightly-bundle-macos/cpsc-bundle-*-Darwin-arm64.tar.xz) bundle_windows=(release-packages/nightly-bundle-windows/cpsc-bundle-*-Windows-x86_64.exe) for count in "${#linux[@]}" "${#macos[@]}" "${#windows[@]}" "${#plugin[@]}" "${#bundle_macos[@]}" "${#bundle_windows[@]}"; do @@ -562,6 +562,30 @@ jobs: for package in "${packages[@]}"; do test -s "$package" done + v='([0-9]{8}-[0-9]{6})-([0-9a-f]{7,40})' + version_of() { + local name + name=$(basename "$1") + if [[ ! "$name" =~ $2 ]]; then + echo "Unexpected package name: $name; leaving the release untouched." >&2 + exit 1 + fi + printf '%s %s' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" + } + linux_v=$(version_of "${linux[0]}" "^cpsc-$v-Linux-x86_64\\.tar\\.xz\$") + macos_v=$(version_of "${macos[0]}" "^cpsc-$v-Darwin-arm64\\.tar\\.xz\$") + windows_v=$(version_of "${windows[0]}" "^cpsc-$v-Windows-[^/]+\\.zip\$") + plugin_v=$(version_of "${plugin[0]}" "^cpsc-plugin-$v\\.vsix\$") + bundle_macos_v=$(version_of "${bundle_macos[0]}" "^cpsc-bundle-$v-Darwin-arm64\\.tar\\.xz\$") + bundle_windows_v=$(version_of "${bundle_windows[0]}" "^cpsc-bundle-$v-Windows-x86_64\\.exe\$") + if [[ "$linux_v" != "$macos_v" || "$linux_v" != "$windows_v" ]]; then + echo "Compiler packages have different versions; leaving the release untouched." >&2 + exit 1 + fi + if [[ "$bundle_macos_v" != "$bundle_windows_v" ]]; then + echo "Bundle packages have different versions; leaving the release untouched." >&2 + exit 1 + fi latest_sha=$(gh api "repos/$GH_REPO/git/ref/heads/main" --jq '.object.sha') if [[ "$latest_sha" != "$GITHUB_SHA" ]]; then echo "This push has been superseded; leaving the release untouched." @@ -573,4 +597,20 @@ jobs: while IFS= read -r asset_id; do gh api --method DELETE "repos/$GH_REPO/releases/assets/$asset_id" done < "$RUNNER_TEMP/nightly-asset-ids" - gh release upload "$CPSC_NIGHTLY_TAG" "${packages[@]}" --clobber + upload="$RUNNER_TEMP/nightly-upload" + mkdir -p "$upload" + latest_files=() + for package in "${packages[@]}"; do + name=$(basename "$package") + [[ "$name" =~ $v ]] + latest_files+=("$upload/${name/${BASH_REMATCH[0]}/latest}") + cp "$package" "${latest_files[-1]}" + done + read -r compiler_time compiler_commit <<< "$linux_v" + read -r plugin_time plugin_commit <<< "$plugin_v" + read -r bundle_time bundle_commit <<< "$bundle_macos_v" + printf '{\n "compiler": { "time": "%s", "commit": "%s" },\n "plugin": { "time": "%s", "commit": "%s" },\n "bundle": { "time": "%s", "commit": "%s" }\n}\n' \ + "$compiler_time" "$compiler_commit" "$plugin_time" "$plugin_commit" "$bundle_time" "$bundle_commit" \ + > "$upload/version.json" + gh release upload "$CPSC_NIGHTLY_TAG" "${latest_files[@]}" --clobber + gh release upload "$CPSC_NIGHTLY_TAG" "$upload/version.json" --clobber diff --git a/AGENTS/ARCH/NIGHTLY.md b/AGENTS/ARCH/NIGHTLY.md index 3e49b9b..76a4f57 100644 --- a/AGENTS/ARCH/NIGHTLY.md +++ b/AGENTS/ARCH/NIGHTLY.md @@ -5,14 +5,14 @@ filters. A shared concurrency group cancels superseded runs. A final publish job requires all four build jobs to succeed before updating the existing `nightly-build` release. Any build or check failure leaves all previous attachments untouched. The publish job deletes all old uploaded assets, including paginated results, -then uploads the six new packages. It never creates or deletes the release +then uploads the six packages under `latest` names, and `version.json` last. It never creates or deletes the release and preserves its tag, title and notes. GitHub's generated source downloads remain available. The native compiler jobs also build CPSC Bundle, reusing their EMBEDDED executable. Linux compiles and tests the app without publishing an installer. Windows x64 adds a standalone .exe and macOS arm64 adds a .tar.xz containing the .app, -both with HEAD-based filenames. Windows embeds its compiler and extracts it into +both with per-product version filenames. Windows embeds its compiler and extracts it into the current working directory on startup; macOS keeps the compiler inside the app. Native runner tests check prefilled input, EOF, diagnostics, output before exit, stopping and restart. Portable packages are checked for the desktop executable, @@ -48,7 +48,13 @@ that exactly one nonempty package exists for each build before any release API calls. It then checks main's current SHA to avoid modifying nightly for a superseded push. Release upload failures do not roll back deleted assets. The workflow uses `GITHUB_TOKEN` with `contents: write`. -Compiler and VSIX package names use HEAD's UTC commit timestamp and short ID. +Each product (compiler, plugin, bundle) is versioned by the last commit touching its +paths, and its package names carry that commit's UTC `YYYYMMDD-HHMMSS-shorthash`. +The publish job validates the names and requires the three compiler packages to +share one version and the two bundles another, before any API call. Release assets +replace that segment with `latest` (for example `cpsc-latest-Darwin-arm64.tar.xz`, +`cpsc-plugin-latest.vsix`, `cpsc-bundle-latest-Windows-x86_64.exe`), and +`version.json` records each product's `time` and `commit`. The VSIX internal version is `YYYYMMDD.HHMMSS.0+commit`, with leading zeros removed from the numeric time component. Before committing workflow changes, run actionlint, simulate release API calls, and smoke-test the packages locally; -- cgit v1.3.1-4-g156e