From 65a44ca1502926d533e6b4b6692779fa39740218 Mon Sep 17 00:00:00 2001 From: Ajay Krishnan Date: Mon, 20 Jul 2026 20:00:22 -0700 Subject: [PATCH] Prepare repaired alpha9 release --- .github/workflows/release.yml | 37 +++++++++++++++++++++++------------ CHANGELOG.md | 9 ++++++++- README.md | 15 +++++++------- lib/opencode/version.rb | 2 +- test/readme_contract_test.rb | 4 +++- test/release_workflow_test.rb | 31 ++++++++++++----------------- 6 files changed, 58 insertions(+), 40 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 708978e..d0d700c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,12 +8,16 @@ on: jobs: verify: runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: ruby: ["3.2", "3.3", "3.4", "4.0"] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up Ruby ${{ matrix.ruby }} uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0 @@ -21,6 +25,15 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true + - name: Verify tag matches gem version + env: + RELEASE_TAG: ${{ github.ref_name }} + run: >- + ruby -Ilib -ropencode/version -e + 'expected = ENV.fetch("RELEASE_TAG").delete_prefix("v"); + abort "tag #{expected.inspect} does not match gem #{Opencode::VERSION.inspect}" + unless Opencode::VERSION == expected' + - name: Run tests run: bundle exec rake test @@ -29,8 +42,18 @@ jobs: - name: Verify gem loads after install run: | - gem install opencode-ruby-*.gem --no-document - ruby -ropencode-ruby -e 'puts Opencode::VERSION' + bundle_gem_path="$(bundle exec ruby -e 'puts Gem.path.join(":")')" + export GEM_HOME="${RUNNER_TEMP}/opencode-ruby-${{ matrix.ruby }}" + export GEM_PATH="${GEM_HOME}:${bundle_gem_path}" + mkdir -p "$GEM_HOME" + gem_file="opencode-ruby-$(ruby -Ilib -ropencode/version -e 'print Opencode::VERSION').gem" + gem install --local "$gem_file" --no-document + ruby -ropencode-ruby -e ' + root = File.realpath(ENV.fetch("GEM_HOME")) + path = File.realpath(Gem.loaded_specs.fetch("opencode-ruby").full_gem_path) + abort "opencode-ruby loaded outside isolated GEM_HOME: #{path}" unless path.start_with?("#{root}/") + puts Opencode::VERSION + ' push: needs: verify @@ -48,14 +71,4 @@ jobs: with: ruby-version: "4.0" bundler-cache: true - - name: Verify tag matches gem version - env: - RELEASE_TAG: ${{ github.ref_name }} - run: >- - ruby -Ilib -ropencode/version -e - 'expected = ENV.fetch("RELEASE_TAG").delete_prefix("v"); - abort "tag #{expected.inspect} does not match gem #{Opencode::VERSION.inspect}" - unless Opencode::VERSION == expected' - - name: Run tests - run: bundle exec rake test - uses: rubygems/release-gem@052cc82692552de3ef2b81fd670e41d13cba8092 # v1.4.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0643a60..2d27a39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.0.1.alpha8 - 2026-07-20 +## 0.0.1.alpha9 - 2026-07-20 ### Fixed @@ -25,6 +25,13 @@ - Fail the trusted-publishing job before release when the pushed tag does not match `Opencode::VERSION`. +## 0.0.1.alpha8 - 2026-07-20 + +### Yanked + +- Published from the unrepaired alpha8 source by mistake and yanked the same + day. Use alpha9, which contains the intended alpha8 fixes and release gates. + ## 0.0.1.alpha7 - 2026-07-18 ### Fixed diff --git a/README.md b/README.md index 92a03ea..78b07db 100644 --- a/README.md +++ b/README.md @@ -237,13 +237,14 @@ The smoke suite covers Client end-to-end against WebMock-stubbed OpenCode endpoints, including subscription-before-prompt ordering and reconnect-without-repost. -The repository contains a tag-triggered `release.yml` workflow intended for -RubyGems trusted publishing, but its RubyGems trusted-publisher registration is -not configured as of `0.0.1.alpha7`; that release was published manually. A -`v*` tag push therefore does not currently guarantee publication. Before a -future release, verify the RubyGems registry result explicitly. Once the -workflow is registered as a trusted publisher for the `release` environment, -it can build, attest, and publish without a long-lived RubyGems API key. +The mistakenly published `0.0.1.alpha8` package contained unrepaired source and +was yanked; use `0.0.1.alpha9` or later. The repository contains a tag-triggered +`release.yml` workflow intended for RubyGems trusted publishing, but its +trusted-publisher registration is not confirmed for alpha9. A `v*` tag push +therefore does not currently guarantee publication. Before a future release, +verify the RubyGems registry result explicitly. Once the workflow is registered +as a trusted publisher for the `release` environment, it can build, attest, and +publish without a long-lived RubyGems API key. ## License diff --git a/lib/opencode/version.rb b/lib/opencode/version.rb index 68247d8..bf03fec 100644 --- a/lib/opencode/version.rb +++ b/lib/opencode/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Opencode - VERSION = "0.0.1.alpha8" + VERSION = "0.0.1.alpha9" end diff --git a/test/readme_contract_test.rb b/test/readme_contract_test.rb index 59474ac..c1f9c29 100644 --- a/test/readme_contract_test.rb +++ b/test/readme_contract_test.rb @@ -13,7 +13,9 @@ class ReadmeContractTest < Minitest::Test end def test_release_guidance_does_not_claim_trusted_publishing_is_configured - assert_includes README, "not configured as of `0.0.1.alpha7`" + assert_includes README, "`0.0.1.alpha8` package contained unrepaired source" + assert_includes README, "was yanked" + assert_includes README, "registration is not confirmed for alpha9" assert_includes README, "does not currently guarantee publication" end diff --git a/test/release_workflow_test.rb b/test/release_workflow_test.rb index b34fb90..008112a 100644 --- a/test/release_workflow_test.rb +++ b/test/release_workflow_test.rb @@ -36,34 +36,25 @@ class ReleaseWorkflowTest < Minitest::Test setup_ruby = steps.find { |step| step["uses"] == SETUP_RUBY_ACTION } assert_equal "4.0", setup_ruby.dig("with", "ruby-version") + assert_equal true, setup_ruby.dig("with", "bundler-cache") assert_equal 1, steps.count { |step| step["uses"] == RELEASE_GEM_ACTION } assert steps.filter_map { |step| step["uses"] }.all? { |uses| uses.match?(/@[0-9a-f]{40}\z/) } - refute steps.any? { |step| step.fetch("run", "").match?(/\bgem\s+push\b/) } + refute steps.any? { |step| step.key?("run") } end def test_release_tag_must_match_the_gem_version_before_publish - steps = push_job.fetch("steps") - preflight_index = steps.index { |step| step["name"] == "Verify tag matches gem version" } - publish_index = steps.index { |step| step["uses"] == RELEASE_GEM_ACTION } + preflight = verify_job.fetch("steps").find { |step| step["name"] == "Verify tag matches gem version" } - refute_nil preflight_index - refute_nil publish_index - assert_operator preflight_index, :<, publish_index - - preflight = steps.fetch(preflight_index) + refute_nil preflight assert_equal "${{ github.ref_name }}", preflight.dig("env", "RELEASE_TAG") assert_includes preflight.fetch("run"), "unless Opencode::VERSION == expected" end - def test_release_runs_the_test_suite_before_publish - steps = push_job.fetch("steps") - test_index = steps.index { |step| step["name"] == "Run tests" } - publish_index = steps.index { |step| step["uses"] == RELEASE_GEM_ACTION } + def test_verification_job_has_read_only_credentials + assert_equal({ "contents" => "read" }, verify_job.fetch("permissions")) - refute_nil test_index - refute_nil publish_index - assert_operator test_index, :<, publish_index - assert_equal "bundle exec rake test", steps.fetch(test_index).fetch("run") + checkout = verify_job.fetch("steps").find { |step| step.fetch("uses", "").start_with?("actions/checkout@") } + assert_equal false, checkout.dig("with", "persist-credentials") end def test_release_verifies_the_supported_matrix_and_installed_gem_before_publish @@ -73,7 +64,11 @@ class ReleaseWorkflowTest < Minitest::Test commands = verify_job.fetch("steps").filter_map { |step| step["run"] }.join("\n") assert_includes commands, "bundle exec rake test" assert_includes commands, "gem build opencode-ruby.gemspec" - assert_includes commands, "gem install opencode-ruby-*.gem --no-document" + assert_includes commands, "bundle exec ruby -e" + assert_includes commands, 'GEM_HOME="${RUNNER_TEMP}/opencode-ruby-${{ matrix.ruby }}"' + assert_includes commands, 'gem_file="opencode-ruby-$(ruby -Ilib -ropencode/version' + assert_includes commands, 'gem install --local "$gem_file" --no-document' + assert_includes commands, "Gem.loaded_specs.fetch(\"opencode-ruby\").full_gem_path" assert_includes commands, "ruby -ropencode-ruby" end end