GitHub Action を触ったことがなかったので、実際に触って複数のシングルバイナリをリリースするようなパイプラインを作ってみたが、いくつかはまりポイントがあったので、シェアしておきたい。
GUIでの操作とタグ付け
GitHubアクションは、各種のアクションを利用するため、GUIで編集したほうが編集しやすいと思われる。例えば今回のケースだと、tagを打ったらリリースを作成するようなパイプラインだったのだ。本来、リリースを作ったらそこにアーカイブだけUploadしたかったのだが、Uploadアクションには、upload_url
というものが必要で、それは、Create Release
アクションの outputs
として渡される仕様になっている。(ハックすればわかるかもしれませんが)だから、GUIでリリースを作るのではなく、コマンドラインでtagを打ってあげないと、Pipelineが「すでにリリースが存在する」という理由でFailします。
自分がはまったのは、変更しても、それが反映されていなかったことで、GUIで編集、自分のPCでタグを打って、git push --tag
とやっても、実はローカルのコミットが進んでおらず、古いコミットに対してタグが付くので、GitHub Actionは古いコミットに対して実行される。すごく当たり前だけど、これで結構はまりました。ちゃんと git pull
した後にタグうちをして、git push --tag
をしないといけません。git log
で tag と commit の関連付けを確認するようにしましょう。
Zip
地味に困ったのがこちらです。GitHub Action のフォーク元の、Azure DevOps では、Zip のタスクがあって、Linux でも、Windows でも動作するものだったのですが、GitHub Actions の場合は、Linuxのみ といったものしか見つけられませんでした。しばらくは、WinとLinux で書き方を変えるしかなさげです。コードを見るとDockerとかを内部で使っていました。多分 Azure DevOps のユーザと違って、GitHub Actions のユーザはLinuxしか意識しない人が多いのかもしれません。
Logging command vs workflow command
後続のタスクに変数を渡したい場合、Azure DevOps では、Logging command というのがありましたが、それに似たので、Workflow command
とうのがあります。書式がずいぶん違いますが、Outputs
の変数を出力して、後続のタスクで使いたい場合は、次の感じです。
echo "::set-output name=action_fruit::strawberry"
Debug の有効化
Debug を有効化させるためには、GitHub のプロジェクトの Secret に 下記の変数をtrueにして登録する必要があります。
一見Debugを有効にしても、ログに変化がないように見えますが、Download log archive
に細かいログが含まれるようになります。
Azure DevOps ユーザ向けリソース
実はインターネットのリソースを見ていると、例えば、Jobのdependencyは、サポートされてないみたいなのを見つけましたが、デマのようです。下記のリソースはとてもよさげで Azure DevOps を使っていた人が、どのように移行するかが書かれています。そこには、dependency の指定も書かれていました。
感想
生まれて初めて触ったにしては、はまったとはいえ、マニュアルをほぼ一切見ずに、リリースの自動作成みたいなのを作ることができました。まだ、まだ Azure DevOps のほうがタスクが充実していたり、ステージの概念があったり、いろいろ便利だなとは思いつつ、これぐらいあっさり GitHub のみで使えるのは軽快感があります。くそショーもないことではまったとはいえ、学習コストが低いのもとてもよかったポイントです。
最後に初めて作ったパイプラインを貼っておきます。
name: .NET Core
on:
push:
tags:
- '*'
jobs:
publish_linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.101
- name: Extract Tag version
id: tag
run: echo "::set-output name=version::$(echo ${{ github.ref }} | sed -e 's/refs\/tags\///')"
- name: Test TAG
run: echo ${{ steps.tag.outputs.version }}
- name: Install dependencies
run: dotnet restore
- name: Publish Linux
run: dotnet publish -c Release -r linux-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=true
- name: Publish Windows
run: dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=false
- name: Create Zip File - Linux
uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-linux-x64.zip ./ExtremeFeedbackDeviceController/bin/Release/netcoreapp3.1/linux-x64/publish
- name: Create Zip File - Windows
uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-win10-x64.zip ./ExtremeFeedbackDeviceController/bin/Release/netcoreapp3.1/win10-x64/publish
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Upload Release Asset - linux
id: upload-release-asset-linux
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-linux-x64.zip
asset_name: ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-linux-x64.zip
asset_content_type: application/zip
- name: Upload Release Asset - windows
id: upload-release-asset-win
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-win10-x64.zip
asset_name: ExtremeFeedbackDeviceController-${{ steps.tag.outputs.version }}-win10-x64.zip
asset_content_type: application/zip