Repository navigation
ci: publish releases to trunk.io/releases/analytics-cli as well as GitHub - #1216
Conversation
…tHub Each release's assets are also uploaded to the trunk-releases bucket under releases/analytics-cli/prod/<version>/, with a manifest of sha256s written last and a channel.json pointer that only the new Promote Release workflow moves. Mirror Releases to S3 backfills releases cut before this lane existed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
😎 Merged successfully - details. |
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1216 +/- ##
==========================================
+ Coverage 83.86% 84.08% +0.21%
==========================================
Files 74 74
Lines 17884 17884
==========================================
+ Hits 14998 15037 +39
+ Misses 2886 2847 -39 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| fi | ||
|
|
||
| jq -nc --arg v "${version}" '{latest: $v}' | | ||
| aws s3 cp - "s3://${bucket}/${prefix}/channel.json" --only-show-errors \ |
There was a problem hiding this comment.
Noting the potential for accidentally overwriting other things here. Acceptable for now, just noting the one potential hole
| role-skip-session-tagging: true | ||
| aws-region: us-west-2 | ||
|
|
||
| # S3 moves first: its preconditions (the role, a complete manifest) are the ones that fail in |
There was a problem hiding this comment.
precondition: I would like to eventually do a FT_VERSION=foo trunk flaky-tests version here as one final check before promoting
There was a problem hiding this comment.
The launcher can't pin a version yet (trunk flakytests only fetches GitHub's latest), so before promoting this runs the published launcher with just that download URL pinned to the version and asserts trunk flakytests --version reports it. There's a TODO to switch to FT_VERSION=… trunk flakytests --version once the launcher supports it. (f0ae2eb)
There was a problem hiding this comment.
Update: I moved this check to #1217, which is stacked on this PR, and reverted the URL-rewrite version here. #1217 runs TRUNK_ANALYTICS_CLI_VERSION=<version> trunk flakytests --version through both the bash launcher and the new CLI, and fails unless both report the version being promoted. The variable is being added to the launcher in trunk-io/trunk#34317 and to the new CLI in trunk-io/trunk2#6728, so #1217 stays a draft until both are released.
Fixes checkov CKV2_GHA_1. release_ruby_gem now gets its id-token explicitly instead of from the repository default. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The launcher only installs GitHub's latest release, so run the published launcher with its download URL pinned to the version being promoted and require `trunk flakytests --version` to report it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ng it" This reverts commit f0ae2eb. The precondition moves to its own PR, which pins the version with TRUNK_ANALYTICS_CLI_VERSION instead of rewriting the launcher's download URL. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Summary
This PR publishes every analytics-cli release to our own bucket as well as to GitHub. The S3 copy is served at
https://trunk.io/releases/analytics-cli/prod/. Theanalytics-uploaderaction and the docs switch to it in follow-up PRs, so they stop depending on GitHub's release download and API rate limits. GitHub releases keep being created, because the frozen legacytrunklauncher and customers' own scripts download from them.Contract
Everything lives in bucket
trunk-releases(account 443897627245, us-west-2) under prefixreleases/analytics-cli/prod/:<version>/<asset>*.tar.gz/*.zipthe GitHub release carries, with the same filename (trunk-analytics-cli-<target>.tar.gz,trunk-analytics-cli-x86_64-pc-windows-gnu-experimental.zip, and theproto-bin-to-json,xcresult-to-junitandcheck-codeownerstarballs). Each hassha256+release-versionobject metadata.<version>/manifest.json{"version":"<ver>","artifacts":{"<filename>":{"sha256":"<hex>"}}}channel.json{"latest":"<ver>"},Content-Type: application/json,Cache-Control: max-age=60<ver>/manifest.jsonexists.Signing is deliberately left out. The release KMS key also signs trunk-cli's manifests, and those signatures are not bound to a path. Giving this public repo
kms:Signon that key would let it produce trunk-cli signatures. Today consumers trust TLS to GitHub, and this keeps the same trust with TLS to trunk.io instead.Changes
.github/scripts/publish-release-to-s3.sh [--skip-complete] <version> <dir>handles uploads, the immutability check and the manifest.--skip-completeturns an already-complete version into a no-op, so a backfill can be re-run. A version left partial (no manifest) re-uploads only the missing objects. Ahead-objectfailure other than 404 aborts the run, so a 403 caused by a missings3:ListBucketis never read as "absent"..github/scripts/set-latest-in-s3.sh <version>writeschannel.json, and refuses when the version has no manifest.release_cli.yml:tag_and_releasepublishes./build/*.tar.gz ./build/*.zipto S3 aftergh release createand leaves the pointer alone. The version stays a prerelease, matching--prerelease --latest=false.release.ymlnow grantsid-token: writeto the called workflow.Promote Release(new) replaces the manual "Set as latest release" step in the GitHub UI. It pointschannel.jsonat the version and marks it latest on GitHub. It refuses prerelease semver and draft releases. S3 goes first because its preconditions (the role and a complete manifest) are the ones that fail in practice, and when they fail GitHub has not moved either. Both steps are idempotent, so if the GitHub edit fails, a re-run converges.Mirror Releases to S3(new) runsgh release download, checks each asset against the sha256 digest GitHub recorded for it (verify-github-digests.sh; GitHub has digests only for releases from0.10.0-beta.0, June 2025, onward, so older ones are copied unchecked), then runs the publish script with--skip-complete, for space-separated tags orall(247 releases, about 45 MB each). Its optionalset-latest-to-github-latestinput pointschannel.jsonat GitHub's current latest release.CONTRIBUTING.mdgains a "Releasing" section.smoke_test.ymlis unchanged. It runs every 2 hours against GitHub's latest release, and between this merge and the backfill nothing exists on S3, so switching it now would page every two hours. Moving it tochannel.jsonis a small follow-up once the backfill has run.Prerequisites (not done by this PR)
trunk-analytics-cli-release-rolein account 443897627245, following trunk2'sdocs/runbooks/trunk-releases-publish-roles.md.repo:trunk-io/analytics-cli:ref:refs/heads/main. This is a public repo, so do not use:*.s3:PutObject/GetObject/AbortMultipartUploadonreleases/analytics-cli/*, pluss3:ListBucketconditioned on that prefix, which the scripts need to tell a 404 from a 403. NoDeleteObjectand no KMS.TRUNK_RELEASES_PUBLISH_ROLE_ARNto the role's ARN.Rollout order
Mirror Releases to S3withtags: allandset-latest-to-github-latest: true, then checkhttps://trunk.io/releases/analytics-cli/prod/channel.json.analytics-uploaderand docs PRs. Pinnedcli-versions need the backfilled history.Releaseand promote withPromote Release.Testing
awsthat emulates S3. Covered cases: fresh publish, republish refused,--skip-completeno-op, resuming a partial version, refusing an asset whose sha differs, aborting on a 403 fromhead-object,set-latestrefused before publish, andset-latestafter publish.shellcheckandshfmtpass on the scripts, andactionlintandyamllintpass on the new and changed workflows.release_cli.yml's compress step already had shellcheck findings, and I did not touch them.trunk checkitself (rust@SYSTEMwas not resolvable on my machine, so I ran the linters directly).🤖 Generated with Claude Code