release: promote dev to main (bootstrap auto-release + atom/template changes)#244
Merged
Conversation
Release v0.2.5.4 # -----BEGIN SSH SIGNATURE----- # U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgaF5RSJNGZfKSwGiA4z8/nTW6L8 # j6Kd5+quTw8zADYtoAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 # AAAAQGpkZBUdzRQUoWUxca0WTzyYt56WRAI3VB3Bdq1S7E7SSXk68dKb03+d2djoVLZZ3y # cSHdACaWZCX4fLAY/oSQM= # -----END SSH SIGNATURE----- # Good "git" signature for mail@charliie.dev with ED25519 key SHA256:DdWGvlMmBCptRDumMUS7sUjoD/W0BCOhLTQnF5Iw+m8
Centralizes the one-shot release driver (validate dev -> snapshot -> mise run all + license/secret scans -> merge dev→main via signed REST Merges API -> tag + create Release) as a reusable workflow, so each repo keeps only a thin workflow_dispatch caller instead of its own copy. Language-agnostic: no actions/setup-go. The toolchain comes entirely from the repo's mise.toml [tools] via jdx/mise-action (pinned to match mise-task.yml), and the build is just `mise run all`. The same driver serves go-service / go-lib / go-cli / frontend (Node) / python / image repos unchanged. - inputs: version, dry_run, use_github_token, runs_on, fetch_depth, mise_version - secrets: ci_read_app_private_key, pre_release_app_private_key (or inherit); App client-ids read from org vars - private-module/submodule fetch via the ci-read App insteadOf rewrite - HAS_CI_APP env bridge (secrets can't be used in step-level if:) Real (non-dry-run) releases require the release App in each repo's main/dev ruleset bypass_actors (org-admin task). dry-run needs neither the App nor bypass. Refs #237, nics-dp/TMDs#580. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s repo Copilot review (meta#238): - pin actions/checkout to v7.0.0 SHA (repo convention; was @v4) - rename input fetch_depth -> fetch-depth (matches mise-task.yml) CodeQL actions-injection: pass github.repository via the GH_REPO env var instead of interpolating ${{ github.repository }} inline in run: blocks — clears the code-injection alerts (no ${{ }} left inside any run shell body). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a preflight step so a self-hosted runs_on group without GitHub CLI fails with a clear error instead of an obscure mid-release "gh: command not found". Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The env var is GH_REPO and run blocks use ${GH_REPO}; the comment said $REPO.
Addresses Copilot review (meta#238).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- checkout persist-credentials: false — don't leave the token in .git/config while `mise run all` runs repo code; private fetch uses the ci-read insteadOf rewrite, not the checkout credential (matches go-release/image-release). - job defaults.run.shell: bash — this driver targets Linux runners; pin bash so a differing default shell still works. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nners The token-bearing `url.*insteadOf` git config is written with --global, which persists across jobs on self-hosted runners that don't reset HOME — risking a stale/expired token being reused or a token-bearing config lingering. - self-healing: drop any stale url.*@github.com/nics-dp insteadOf sections before writing this run's fresh rewrite - always() teardown step removes the rewrite at the end Mirrors go-release.yml. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The revoke step removed only the trailing-slash section it wrote; reuse the same regex matcher as the setup self-heal so both slash and no-slash token-bearing url.*@github.com/nics-dp sections are cleared from a self-hosted runner's global git config. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Real releases always go through the release App (in the main/dev ruleset bypass_actors); a GITHUB_TOKEN-created Release does not trigger release.yml, so the "real release on a test repo" path it served was broken by design. Validation is covered by dry_run. Removing it now (no callers yet) simplifies the token conditionals and removes a foot-gun. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The create-ref and merges calls already POST implicitly (gh switches to POST when -f fields are present), but the adjacent ref-update call uses an explicit -X PATCH. Add -X POST to both writes so the HTTP method is unambiguous and consistent. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- drop unused `pull-requests: read` permission (no step reads PRs) - run the insteadOf-revoke teardown unconditionally (always()) instead of only when this run minted a ci-read token, so a stale token-bearing config left by a prior interrupted self-hosted run is still swept even when this run has no token Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…typo The duplicate-tag guard and pre-merge re-check use git/ref/<ref> (singular) — the "get a single reference" endpoint that 200s if the exact tag exists and 404s if not, which is correct for an existence check. Add a note so it isn't mistaken for a typo of the plural git/refs/ (list) endpoint. No behavior change. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This workflow makes no local commit (merge is server-side via the REST API), so git user.name/email are unused — and writing them with --global would clobber a self-hosted runner's identity across jobs. Remove them (matches go-release.yml). Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…onse Capture the merges API response and use its .sha as MAIN_SHA instead of re-reading refs/heads/main after the call. The re-read could in principle race a concurrent advance (already bounded by the concurrency group + main ruleset), and on a 204 (main already contains the snapshot) the re-read still falls back to main's tip. Tagging the merge commit directly is unambiguous. Add jq to the preflight since it's now used to parse the response. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the merges API returns 204 (main already contains TARGET_BRANCH), main may have advanced past the snapshot (e.g. a hotfix merged straight to main). Tag the snapshot commit (TARGET_BRANCH) this run validated instead of main's tip; it is reachable from main, so the tag is valid. Addresses Copilot review (meta#238). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- snapshot existence/dev SHA reads use singular git/ref/<ref> (exact, 404 if absent) instead of plural git/refs/<ref>, which prefix-matches and could return an array for a longer sibling branch - drift check uses git status --porcelain so a new untracked file from a generate step is caught, not just tracked modifications
Both the duplicate-tag guard and the pre-merge TOCTOU re-check used a bare `if gh api …; then`, treating every non-2xx (403/5xx/network/ rate-limit) as 'tag absent' and proceeding. A transient failure could then advance main and only fail at release creation. Capture stderr and tri-state on the HTTP status: 200 exists (abort), clean 404 absent (proceed), anything else is a hard error.
ci(auto-release): language-agnostic reusable release driver
Squash of meta#240 (TMDs#239). Three changes: - 8 go atoms declare depends=[go:install] (fix vendor race at source; mirrors node atoms). - 4 facade templates: all = sequential init/generate/api-fix then parallel build/test/ci, descriptions clarified. - init gains depends_post=[meta:bump]; update reworked to run-array with meta:bump as a pre-step (fresh atoms). Closes #241.
Squash of meta#242 (TMDs#239). Adds [tasks.all]=[iac:actionlint, ci] and .github/workflows/self-release.yml (workflow_dispatch caller of auto-release.yml@main) so meta can dogfood its own release driver. meta [tasks.ci] dropped trivy-license (driver runs it separately). self-release.yml uses least-privilege perms (workflow read + job write). Closes #243.
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
| cancel-in-progress: false | ||
|
|
||
| permissions: | ||
| contents: write # GITHUB_TOKEN creates the release/<version> or ci/release/<version> snapshot (unprotected) |
| jobs: | ||
| self-release: | ||
| permissions: | ||
| contents: write # auto-release.yml's GITHUB_TOKEN creates the release snapshot branch + tag/release |
| self-release: | ||
| permissions: | ||
| contents: write # auto-release.yml's GITHUB_TOKEN creates the release snapshot branch + tag/release | ||
| uses: nics-dp/meta/.github/workflows/auto-release.yml@main |
Contributor
There was a problem hiding this comment.
Pull request overview
此 PR 將新的自動發版基礎建設(可重用的 auto-release driver)與相關 mise/模板調整從 dev 推進到 main,讓所有 @main 呼叫端(含 meta 自身 self-release 與多個 consumer)能正常使用一致的發版流程與 mise run all 驗證入口。
Changes:
- 新增可重用的 GitHub Actions
auto-release.yml發版 driver,並加入 meta 的self-release.ymlcaller 以啟用 meta 自我發版。 - meta repo 新增
mise.toml的[tasks.all]作為 auto-release driver 的驗證入口(actionlint + CI scans),並避免與 driver 內的 license/secret scans 重複。 - 更新 facade templates 的
update/all執行順序(用run分開 invocation 避免 cache clear 競態),以及讓多個 Go tasks 明確依賴go:install。
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/facades/mise.python.toml | 調整 update/all 為分段 run,並在 init 後追加 meta:bump。 |
| templates/facades/mise.go-service.toml | update 改為先 meta:bump 再更新;all 改為先序列 generate/api-fix,再並行 build/test/ci。 |
| templates/facades/mise.go-lib.toml | 同步 update/all 執行模型(先 bump 再更新;關鍵步驟序列化)。 |
| templates/facades/mise.frontend.toml | update/all 改為分段 run,避免 meta:bump 清 cache 競態。 |
| mise.toml | 新增 [tasks.all] 作為 auto-release driver 入口;ci 依賴調整以避免重複掃描。 |
| .mise/tasks/go/test | 增加 #MISE depends=["go:install"],確保 vendoring 完成後再測試。 |
| .mise/tasks/go/sast | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/lint-check | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/generate | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/dead-code | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/build | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/audit | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .mise/tasks/go/api-fix | 增加對 go:install 的依賴,避免 vendoring 競態。 |
| .github/workflows/self-release.yml | 新增 meta 的 self-release caller,呼叫 auto-release.yml@main。 |
| .github/workflows/auto-release.yml | 新增 reusable auto-release driver(snapshot/validate/merge/tag/release)。 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+148
to
+155
| if err="$(gh api "repos/${GH_REPO}/git/ref/tags/${VERSION}" 2>&1 >/dev/null)"; then | ||
| echo "::error::Tag ${VERSION} already exists — refusing to re-release." | ||
| exit 1 | ||
| fi | ||
| case "$err" in | ||
| *"HTTP 404"*) echo "No existing tag ${VERSION}." ;; | ||
| *) echo "::error::tag existence check failed (not a 404, refusing to proceed): ${err}"; exit 1 ;; | ||
| esac |
Comment on lines
+291
to
+298
| if err="$(gh api "repos/${GH_REPO}/git/ref/tags/${VERSION}" 2>&1 >/dev/null)"; then | ||
| echo "::error::Tag ${VERSION} appeared during validation — aborting before touching main." | ||
| exit 1 | ||
| fi | ||
| case "$err" in | ||
| *"HTTP 404"*) echo "Tag ${VERSION} still absent — proceeding to merge." ;; | ||
| *) echo "::error::tag re-check failed (not a 404, refusing to touch main): ${err}"; exit 1 ;; | ||
| esac |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First promotion of the new auto-release infrastructure to main, breaking the bootstrap deadlock: every
@maincaller (meta self-release + 13 consumers) needsauto-release.ymlto exist on main, but it currently only lives on dev.Brings to main: auto-release.yml driver (#238), go:install atom deps + facade
allsequencing + meta:bump wiring (#240), and meta self-release enablement (#242).After this merge:
@maincallers work, consumergo:installatom deps take effect, and future meta releases run via the Self-Release driver. Tag v0.2.5.5 + GitHub Release will be created on the merged main.