📦

GitHub Packages に NuGetパッケージを登録する GitHub Actions

2021/01/31に公開

GitHub Packagesについて

https://github.com/features/packages

NuGetパッケージは https://www.nuget.org/ に登録するのが一般的ですが、これはGitHubによるホスティングサービスです。.NETのNuGetを含めて5種のパッケージをサポートしています (参考)。

成果物としてNuGetパッケージを作成するようなCIワークフローは一般的だと思います。本記事では、そうしてパッケージングしたのちにGitHub Packagesに登録するGitHub Actions構築方法を書き残します。

出来上がりの例

https://github.com/shimat?tab=packages

GitHubのユーザプロファイルのページに Packages というメニューがあり、そこから確認することができます。

GitHub Packagesの使いどころ

ワークフローを書く前にGitHub Packagesの性質を調べておきます。結論として privateリポジトリ向きで、publicリポジトリには向かない(使い道があまりない) と捉えています。なお筆者は現時点でろくに運用できていないので理解不足かもしれません。

publicであってもトークンが無いとアクセスできないという点で不特定多数への公開には向かず、せっかく容量無制限なのですが用途は限られそうです。publicリポジトリだけれどもNuGetパッケージはアクセス制御されているという状態の使い道があまり筆者には思いつきません。大抵はprivate向けにうまくはまるサービスであろうと思いました。アクセス制御できるNuGetのホスティングサービスは貴重です。

パッケージを利用する場合のアクセストークンについては、公式リファレンスにあるように nuget.config に以下のような設定をすることになります。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="github" value="https://nuget.pkg.github.com/OWNER/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="USERNAME" />
            <add key="ClearTextPassword" value="TOKEN" />
        </github>
    </packageSourceCredentials>
</configuration>

GitHub Actions ワークフロー

基本形

まず基本形です。.github/workflows/dotnet.yml のような名前で作成します。

  • 何かコードがpushされるたび発動し、
  • NuGetパッケージを構築し、
  • GitHub Actionsのアーティファクトとしてアップロードする

・・・までを行います。

name: .NET

on:
  push:

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:    
      - uses: actions/checkout@v2
    
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '5.0.x'
	
      - name: Install dependencies
        run: |
          dotnet restore
      
      - name: Build
        run: |
          dotnet build --configuration Release --no-restore
      
      - name: Pack
        run: |
          dotnet pack MyGreatLib.csproj -o artifacts/

      - uses: actions/upload-artifact@v1
        with:
          name: artifacts
          path: artifacts

.csprojの編集

以下基本的には公式のリファレンスに載っている通りなのですが、若干違うことをしているので書き残している次第です。
https://docs.github.com/en/packages/guides/configuring-dotnet-cli-for-use-with-github-packages

ビルドするプロジェクトの.csprojファイルに、GitHubを指し示した <RepositoryUrl>要素が最低限必須のようです。予め追加しておきます。

これは.nupkgの作り方によりまして、.nuspecを使うなどほかの方法であればこちらを参照しましょう。https://devblogs.microsoft.com/nuget/introducing-source-code-link-for-nuget-packages/

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <PackageId>MyGreatLib</PackageId>
    <Version>1.0.0</Version>
    <Authors>your-name</Authors>
    <PackageDescription>Hello world!</PackageDescription>
    <RepositoryUrl>https://github.com/[user]/[repository-name]</RepositoryUrl>
  </PropertyGroup>
</Project>

Personal Access Tokenの準備

自分のGitHubアカウントの設定画面から Developer settings へ進み、Personal access tokens から新しいトークンを作成します。

write:packages にだけチェックを入れます。

続いて対象リポジトリの設定から Secrets を選択し、作成したアクセストークンの文字列を設定します。ここでは GH_PACKAGES_PAT という名前になっています。[1]

GitHub Packages へのアップロード

ワークフローの最後に処理を追加します。github という名前でGitHub Packagesのパッケージソースを追加し、そこへ向けて.nupkgをアップロードします。

- name: Publish to GitHub Packages
  run: |
    dotnet nuget add source "https://nuget.pkg.github.com/<user>/index.json" -n "github" -u <user> -p ${{secrets.GH_PACKAGES_PAT}} --store-password-in-clear-text
    dotnet nuget push "*.nupkg" --api-key ${{secrets.GH_PACKAGES_PAT}} --source "github" --skip-duplicate

ここで注意として、dotnet nuget add source コマンドは結構最近になって追加されたもので、.NET Core 3.1.200 より前だと使えません。actions/setup-dotnetで新しいバージョンを指定するのがよいでしょう。

また、nuget.config でGitHub Packagesのパッケージソースを定義してある場合は dotnet nuget add source は不要だと思います。普段は参照しないけれどCIの時にGitHub Packagesへ登録だけしたいという筆者の用途を反映しています。

おわりに

  • NuGetパッケージを作成してGitHub Packagesに登録していくGitHub Actionsワークフローを定義できました。
  • 当初はOSSにて、Nightly build的な感覚でbetaパッケージを気軽に置ける場として使えないだろうかと考えたのがきっかけでした(都度nuget.orgにアップするのは過剰な気がしました)。結論としてはあまりそれには適していないと考えられ、privateな社内利用のほうが検討のしがいがありそうです。
  • 一応はできたけれども所々理解が怪しいという状態で、おかしな点があればすみません。
脚注
  1. GITHUBから始まる名前は予約されていて設定できないようです。 ↩︎

Discussion