Skip to content

feat: add release automation script#1992

Open
TerryHowe wants to merge 12 commits intooras-project:mainfrom
TerryHowe:feature/release-script
Open

feat: add release automation script#1992
TerryHowe wants to merge 12 commits intooras-project:mainfrom
TerryHowe:feature/release-script

Conversation

@TerryHowe
Copy link
Copy Markdown
Member

Summary

Adds scripts/release.sh, a bash release automation script that codifies the manual steps from https://oras.land/community/release-process into four repeatable phases.

Phases

  • prep <version> - Validates semver format, checks gh/gpg prerequisites, updates internal/version/version.go (sets Version, clears BuildMetadata), creates branch chore/release-v<version>, commits, pushes, creates a PR titled "bump: tag and release ORAS CLI v<version>" targeting main (or the release branch for patches), and prints the commit SHA with a Slack vote template.

  • tag <version> <sha> - Validates that the commit at the given SHA contains the correct version and cleared BuildMetadata, creates a signed git tag v<version>, pushes the tag, and creates a release branch (e.g. release-X.Y) for new minor versions (patch==0, no pre-release suffix).

  • validate <version> - Polls the release-ghcr and release-github GitHub Actions workflows until they complete, runs make fetch-dist to download artifacts, verifies checksums with shasum, and tests the linux/amd64 binary reports the expected version.

  • publish <version> - Runs make sign to GPG-sign artifacts, verifies all GPG signatures, uploads .asc files to the GitHub release, appends signing key verification instructions to release notes, publishes the release (--draft=false), triggers the snap workflow, cleans up _dist/, and prints a post-release Slack template.

Features

  • --dry-run flag for safe testing
  • ORAS_REMOTE env var to configure the upstream remote (default: upstream)
  • Color-coded output for readability
  • Confirmation prompts before all destructive actions
  • Slack templates for vote and announcement

Makefile Targets

Also adds convenience Makefile targets: release-prep, release-tag, release-validate, release-publish.

Test plan

  • Run scripts/release.sh --help to verify usage output
  • Run scripts/release.sh --dry-run prep 1.3.0 to verify prep phase logic
  • Run scripts/release.sh --dry-run tag 1.3.0 abc1234 to verify tag phase logic
  • Run scripts/release.sh --dry-run validate 1.3.0 to verify validate phase logic
  • Run scripts/release.sh --dry-run publish 1.3.0 to verify publish phase logic
  • Verify make help shows the new release targets

Signed-off-by: Terry Howe <terrylhowe@gmail.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.21%. Comparing base (5ff6606) to head (588a78e).
⚠️ Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1992      +/-   ##
==========================================
+ Coverage   87.18%   87.21%   +0.03%     
==========================================
  Files         143      143              
  Lines        5539     5539              
==========================================
+ Hits         4829     4831       +2     
+ Misses        423      421       -2     
  Partials      287      287              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new scripts/release.sh automation script to codify the ORAS CLI release process into repeatable phases, and exposes those phases via make targets for convenience.

Changes:

  • Added scripts/release.sh implementing prep, tag, validate, and publish release phases (with --dry-run support).
  • Added Makefile targets (release-prep, release-tag, release-validate, release-publish) to invoke the script.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.

File Description
scripts/release.sh New bash script that automates version bump PR creation, tagging, CI/artifact validation, and publishing/signing steps.
Makefile Adds convenience targets to run the release script phases via make.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh
Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh
Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh Outdated
Comment thread scripts/release.sh Outdated
- Extract check_prerequisites() as shared function called from both
  do_prep and do_tag, ensuring GPG/gh/remote are validated before tagging
- Add dirty working tree guard in do_prep before creating branch
- Add portable checksum verification: prefer sha256sum over shasum with
  fallback and fatal error if neither is available
- Use make SHELL=/bin/bash sign to avoid POSIX brace glob issue
- Fix .asc upload to avoid glob expansion in dry-run mode
- Fix snap workflow: use release-snap.yml with required version and
  isStable fields, pass --ref for correct trigger

Signed-off-by: Terry Howe <terrylhowe@gmail.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
Copy link
Copy Markdown
Contributor

@sabre1041 sabre1041 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks really good. one small comment

Comment thread Makefile Outdated
TerryHowe and others added 9 commits April 18, 2026 06:50
- Replace make fetch-dist with gh release download in validate phase
  so artifact fetching works against draft releases (curl on the public
  /releases/download/ URL returns 404 for drafts)
- Add ORAS_REPO variable to Makefile so the repo is not hardcoded
- Add gh CLI prerequisite check to fetch-dist target with install URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
- Replace make sign with a direct gpg loop covering all artifact types
  including .zip (make sign only covered *.{gz,txt})
- Fail immediately if any gpg signing fails instead of swallowing errors
- Scope verify and upload globs to oras_<version>_* to avoid picking up
  leftover files from prior releases
- Add --clobber to gh release upload so publish is safely retryable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
Bash arithmetic (( expr )) exits with code 1 when the expression
evaluates to 0. Post-increment (( n++ )) returns the old value, so
the first increment from 0 to 1 silently kills the script under
set -euo pipefail. Use $(( n + 1 )) assignment instead.

Affected: attempt counter in validate and sig_count in publish.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
gpg consumes stdin during signing, leaving confirm's read at EOF which
silently treats the response as empty (N) and aborts. Reading from
/dev/tty ensures interactive prompts always reach the terminal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
- Remove all confirm() calls and the confirm function itself; the script
  now runs non-interactively without pausing for user input
- Replace the branch warning in prep with a hard failure: the current
  branch must be 'main' or 'release-X.Y' where X.Y matches the
  major.minor of the version being released (e.g. v1.3.2 requires
  main or release-1.3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
validate and publish now read the version from internal/version/version.go
when no version argument is supplied, so running just
'scripts/release.sh validate' or 'scripts/release.sh publish' works
from the release branch without repeating the version string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
When running prep from 'main', the version's major.minor must match
MAIN_RELEASE_VERSION (default 2.0). This prevents accidentally cutting
a 1.x patch release from main. Override with ORAS_MAIN_RELEASE_VERSION
when the next main-branch series changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
…N from validate/publish make targets

- Remove redundant *Changelog:* line from the publish Slack announcement
  (it was the same URL as *Release:*)
- Drop $(VERSION) from release-validate and release-publish Makefile
  targets since the script now reads the version from version.go

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants