GitHub Action を生まれて初めて触ってみてはまったこと

GitHub Action を触ったことがなかったので、実際に触って複数のシングルバイナリをリリースするようなパイプラインを作ってみたが、いくつかはまりポイントがあったので、シェアしておきたい。

# GUIでの操作とタグ付け
GitHubアクションは、各種のアクションを利用するため、GUIで編集したほうが編集しやすいと思われる。例えば今回のケースだと、tagを打ったらリリースを作成するようなパイプラインだったのだ。本来、リリースを作ったらそこにアーカイブだけUploadしたかったのだが、Uploadアクションには、`upload_url` というものが必要で、それは、`Create Release` アクションの `outputs`として渡される仕様になっている。（ハックすればわかるかもしれませんが）だから、GUIでリリースを作るのではなく、コマンドラインでtagを打ってあげないと、Pipelineが「すでにリリースが存在する」という理由でFailします。

* [Upload Release Asset](https://github.com/actions/upload-release-asset)

自分がはまったのは、変更しても、それが反映されていなかったことで、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"
```

* [workflow command](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions)

# Debug の有効化

Debug を有効化させるためには、GitHub のプロジェクトの Secret に 下記の変数をtrueにして登録する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/d48bda62-a706-d11b-12db-c8d8e40bf5e8.png)

一見Debugを有効にしても、ログに変化がないように見えますが、`Download log archive`に細かいログが含まれるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/c0c0898f-039f-d787-4757-95266080fc69.png)

# Azure DevOps ユーザ向けリソース

実はインターネットのリソースを見ていると、例えば、Jobのdependencyは、サポートされてないみたいなのを見つけましたが、デマのようです。下記のリソースはとてもよさげで Azure DevOps を使っていた人が、どのように移行するかが書かれています。そこには、dependency の指定も書かれていました。

* [Migrating from Azure Pipelines to GitHub Actions](https://docs.github.com/en/actions/migrating-to-github-actions/migrating-from-azure-pipelines-to-github-actions#:~:text=In%20GitHub%20Actions%2C%20the%20default%20shell%20for%20scripts,Command%20shell%20script%20in%20PowerShell%20without%20any%20changes.)

# 感想

生まれて初めて触ったにしては、はまったとはいえ、マニュアルをほぼ一切見ずに、リリースの自動作成みたいなのを作ることができました。まだ、まだ Azure DevOps のほうがタスクが充実していたり、ステージの概念があったり、いろいろ便利だなとは思いつつ、これぐらいあっさり GitHub のみで使えるのは軽快感があります。くそショーもないことではまったとはいえ、学習コストが低いのもとてもよかったポイントです。

最後に初めて作ったパイプラインを貼っておきます。

```yml
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
  
  
```