From 113ac0a5ef1f3b7e51c41df0c0a8f9552add9c6c Mon Sep 17 00:00:00 2001 From: Brady Holt Date: Wed, 19 Aug 2026 17:38:03 -0500 Subject: [PATCH] Set the release version in the repo instead of in CI The publish workflow bumped the version itself and relied on bundler's release task to push the bump commit to main, which the tier-1-repos org ruleset blocks for the github-actions app -- hence the GH_API_TOKEN PAT. It also left Gemfile.lock a release behind, since bundle install ran before the bump. The version now comes from lib/ynab/version.rb on main, set by the same PR that regenerates the client. rake generate takes an optional major/minor/patch argument (defaulting to minor) and bump_version_number re-resolves Gemfile.lock so the two stay in sync. Publish only runs the specs, pushes the gem, and tags the commit it checked out, all of which GITHUB_TOKEN can do, so GH_API_TOKEN can be deleted from repo secrets. The release tag is now the annotated v-prefixed tag rather than a second bare one created by action-gh-release alongside it. --- .github/workflows/publish.yml | 40 ++++++++++++++++++----------------- DEVELOPMENT.md | 9 +++++--- Gemfile.lock | 2 +- Rakefile | 17 ++++++++------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2d81278..95a4515 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,15 +1,6 @@ name: Publish on: workflow_dispatch: - inputs: - version_type: - type: choice - description: Version type - default: minor - options: - - major - - minor - - patch jobs: publish: runs-on: ubuntu-latest @@ -19,11 +10,7 @@ jobs: pull-requests: write # comment on PRs included in the release steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - token: ${{ secrets.GH_API_TOKEN }} - name: Setup git repo - env: - GH_API_TOKEN: ${{ secrets.GH_API_TOKEN }} run: | git config user.name $GITHUB_ACTOR git config user.email gh-actions-${GITHUB_ACTOR}@github.com @@ -37,21 +24,36 @@ jobs: run: | gem install bundler bundle install --jobs 4 --retry 3 - - name: Bump Version - id: bump_version + - name: Resolve version to publish + id: version + run: | + version=$(rake get_current_version) + echo "version=${version}" >> $GITHUB_OUTPUT + echo "tag-name=v${version}" >> $GITHUB_OUTPUT + - name: Verify the release tag does not already exist + env: + TAG_NAME: ${{ steps.version.outputs.tag-name }} run: | - NEW_VERSION=$(rake "bump_version_number[${{ inputs.version_type }}]") - echo "NEW_VERSION=$NEW_VERSION" - echo "new_version=$(echo $NEW_VERSION)" >> $GITHUB_OUTPUT + if git ls-remote --exit-code --tags origin "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then + echo "::error::Tag ${TAG_NAME} already exists. Bump the version in lib/ynab/version.rb first." + exit 1 + fi - name: Configure authentication to RubyGems (trusted publishing) uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0 - name: Publish to RubyGems run: rake publish + - name: Tag the release commit + env: + VERSION: ${{ steps.version.outputs.version }} + TAG_NAME: ${{ steps.version.outputs.tag-name }} + run: | + git tag -a "${TAG_NAME}" -m "Version ${VERSION}" + git push origin "${TAG_NAME}" - name: Create a Release id: create-release uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: - tag_name: ${{ steps.bump_version.outputs.new_version }} + tag_name: ${{ steps.version.outputs.tag-name }} generate_release_notes: true - name: Comment on PRs with link to release they are included in uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 17a3022..5ae0239 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -8,10 +8,13 @@ ## Generating -Run `bundle exec rake generate`. This will generate the API client from the latest OpenAPI spec. Once generated, you should open a PR and merge the changes. +Run `bundle exec rake generate`. This will generate the API client from the latest OpenAPI spec and bump the version. The bump defaults to `minor`; pass `major` or `patch` to change it (`bundle exec rake "generate[patch]"`). Once generated, you should open a PR and merge the changes. ## Publishing -Run the "Publish" GitHub Actions workflow +The version that gets published is whatever `lib/ynab/version.rb` on the `main` branch says, so publishing is two steps. -Note: Use the Publish workflow to bump the version number in `lib/ynab/version.rb` +1. Merge a PR that sets the new version. `bundle exec rake generate` does this for you. For a release that does not involve re-generating the client, run `bundle exec rake "bump_version_number[minor]"` (or `major` / `patch`), which updates `lib/ynab/version.rb` and `Gemfile.lock` without creating a commit or tag. +2. Run the "Publish" GitHub Actions workflow. This runs the specs and publishes that version to RubyGems, then tags the commit and creates a GitHub release. + +The workflow never changes the version itself. If the version in `lib/ynab/version.rb` has already been released, the workflow fails before publishing anything. diff --git a/Gemfile.lock b/Gemfile.lock index b5347a2..b2bbec9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - ynab (5.1.0) + ynab (5.2.0) typhoeus (~> 1.0, >= 1.0.1) GEM diff --git a/Rakefile b/Rakefile index e23af0b..a43be9e 100644 --- a/Rakefile +++ b/Rakefile @@ -12,8 +12,8 @@ end task :default => [:spec] -desc "Run OpenAPI Generator to update the client from the spec" -task :generate do +desc "Run OpenAPI Generator to update the client from the spec and bump the version" +task :generate, [:version_type] do |t, args| spec_filename = 'open_api_spec.yaml' # Download latest spec sh "wget https://api.ynab.com/papi/#{spec_filename} -O ./#{spec_filename}" @@ -21,6 +21,8 @@ task :generate do sh "rm -r docs/ lib/ynab/models/" # Generate the client sh "openapi-generator generate -i ./#{spec_filename} -g ruby -c openapi-generator-config.yaml -o ./" + + Rake::Task[:bump_version_number].invoke(args[:version_type] || 'minor') end task :get_current_version do @@ -49,13 +51,12 @@ task :bump_version_number, [:version_type] do |t, args| new_version_file_text = current_version_file_text.gsub(current_version, new_version) File.open(version_file_path, "w") {|file| file.puts new_version_file_text } - puts new_version -end + # Gemfile.lock pins this gem's own version, so it has to be re-resolved + sh "bundle lock" -task :commit_version_bump do - sh "git add lib/ynab/version.rb Gemfile.lock && git diff-index --quiet HEAD || git commit -m 'Bumping version for release'" + puts new_version end -desc "Bump version, run specs build a gem and release on RubyGems" -task :publish => ['spec', 'commit_version_bump', 'clobber', 'release'] +desc "Run specs, build a gem and release it on RubyGems" +task :publish => ['spec', 'clobber', 'release:rubygem_push']