0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RubyAdvent Calendar 2024

Day 23

GitHub Actions から Credentials 管理不要で gem を push できるようになった

Last updated at Posted at 2024-12-23

去年の12月頃に Trusted Publishing という機能が RubyGems.org に入った。

これは 「指定した GitHub リポジトリの指定した Workflow に対して、(指定した) gem の push を認可する」機能。これを設定すると、GitHub Actions で Credentials の登録をすることなく gem を push 出来るようになる。

この機能は内部的には、 Open ID Connect (OIDC) を利用していて、これにより short-lived な access token を都度取得出来る。

この方法だと通常は ↑ の記事にあるようなトークンの交換処理を行う必要があるのだが、以下の Custom Action を使うことで、簡単にトークンの交換や gem の release が行える。

この記事では、 release-gem Action を利用して、GitHub Actions から gem のリリース出来るようにする流れを説明する。

1. RubyGems.org 側で Trusted Publishing の設定を行う

(※ https://guides.rubygems.org/trusted-publishing/adding-a-publisher/ の内容とほぼ同じ)

(RubyGems.org にログインした状態で、) 設定を行いたい Gem のページの Link から、 信頼できる発行元 (または Trusted Publishers) を選択し、遷移先の画面から 作成 (または Create) を選ぶ。

スクリーンショット 2024-12-23 13.40.46.png

スクリーンショット 2024-12-23 13.41.12.png

すると、登録フォームに遷移する。

スクリーンショット 2024-12-23 13.41.20.png

このフォームで、

  • 認可するリポジトリ (Repository Owner / Repository Name の項目)
  • 認可する GitHub Workflow のファイル名
  • 認可する Environment

を入力し、Rubygem Trusted publisher を作成 (または Create Rubygem Trusted publisher) で登録完了。

Environment は任意だが、実行ブランチの制限や実行時のレビュー必須化など、保護機能が追加で備わっているのでおすすめ。

(新規の gem に対しても似たような手順で設定が行える。詳しくは https://guides.rubygems.org/trusted-publishing/pushing-a-new-gem/ を参照。)

2. release-gem Action を使って Workflow を実装する

(※ https://guides.rubygems.org/trusted-publishing/releasing-gems/ の内容がベース)

https://github.com/marketplace/actions/release-gem を使った、こういう感じの Workflow を実装する。

# ファイル名は、 1. で登録したファイル名にする
name: Release Gem on RubyGems.org

on:
  # push でも workflow_dispatch でもどっちでも OK
  push:
    tags:
      - v*
  workflow_dispatch:

jobs:
  push:
    runs-on: ubuntu-latest
    # 1. で登録した Environment 名にする必要がある
    environment: release

    permissions:
      contents: write
      id-token: write

    steps:
      - uses: actions/checkout@v4

      # `gem exec` が使えるバージョンの rubygems gem が必要。(後述)
      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
          ruby-version: ruby
          # rubygems: latest

      - uses: rubygems/release-gem@v1

release-gem Action が行っていることはざっくり以下の通り。

  1. OIDC を利用し、RubyGems.org の short-lived な access token を取得
  2. rake release を実行して gem のリリースを行う
    • この際に rubygems gem に patch を当てていて、可能なら署名を行いつつ gem を push する

この際に実行している rake release というのは、Bundler が提供している gem の release 用のタスクで、

  • version tag を打って git push
  • rubygems への gem の push

を行ってくれる。

(Rakefile 内で require "bundler/gem_tasks" とすると使える。 bundle gem とかで gem を作っていると最初から入っている。)

※ rubygems gem のバージョンが古いと gem exec が実行できずエラーになる

とまあ、便利な release-gem なのだが、 Ruby 3.1.x など、古めの version で動かすと、以下のようなエラーになる。

image.png

ERROR:  While executing gem ... (Gem::UnknownCommandError)
    Unknown command exec
	/opt/hostedtoolcache/Ruby/3.1.6/x64/lib/ruby/3.1.0/rubygems/command_manager.rb:198:in `find_command'
	/opt/hostedtoolcache/Ruby/3.1.6/x64/lib/ruby/3.1.0/rubygems/command_manager.rb:183:in `process_args'
	/opt/hostedtoolcache/Ruby/3.1.6/x64/lib/ruby/3.1.0/rubygems/command_manager.rb:149:in `run'
	/opt/hostedtoolcache/Ruby/3.1.6/x64/lib/ruby/3.1.0/rubygems/gem_runner.rb:51:in `run'
	/opt/hostedtoolcache/Ruby/3.1.6/x64/bin/gem:21:in `<main>'

これは release-gem が gem exec (npx, npm exec の ruby 版) という機能を使っていて、 gem exec が入ったのが rubygems gem 3.4.8 というそこそこ新し目のバージョンのため。

このエラーを回避するには、 setup-ruby 側で rubygems: 3.4.8 を指定するか、rubygems gem のデフォルトバージョンが新しいもの (3.2.6 以降など) を指定すると良い。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?