Alternative Architecture DOJO

オルターブースのクラウドネイティブ特化型ブログです。

nektos/actをローカルやdevcontainerで試す

こんにちは、MLBお兄さんこと松村です。
MLB はウインターミーティングも終わり、怒涛の移籍ラッシュが落ち着いたと思いきや、ソフトバンクホークスの千賀投手のニューヨーク・メッツとの5年契約が報道されました。
我がニューヨーク・ヤンキースは今のところ静かなオフとなっています。

このブログは2つのアドベントカレンダーの記事となっています。


GitHub 熱の高い最近の私ですが、先日 GitHub Japan で開催された「Go fast and robust with GitHub」で登壇をしてきました。イベントレポートについてはこちら。

aadojo.alterbooth.com

イベント後半に行われた GitHub の CEO や VP との座談会セッションのなかで、GitHub Actions をローカル環境で動かすためのツール nektos/act が紹介されました。

twitter.com

nektos/act とは、GitHub Actions をローカル環境で動かすためのオープンソースです。
GitHub 公式ツールではありませんが、CEO が紹介するくらいですので GitHub 内でも認知されているようです。

github.com

nektos/act を動かすには Docker が必要となります。Docker Desktop でも Docker Engine でも良いです。
なお、私は WSL2 Ubuntu にインストールしている Docker Engine で試しています。

インストールする

まずは nektos/act を Ubuntu に直接インストールします。

$ curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  9886  100  9886    0     0  24358      0 --:--:-- --:--:-- --:--:-- 24349
nektos/act info checking GitHub for latest tag
nektos/act info found version: 0.2.34 for v0.2.34/Linux/x86_64
nektos/act info installed ./bin/act

$ act -h
Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.

Usage:
  act [event name to run] [flags]

(中略)

ワークフローを一覧表示する

とりあえずコマンドをいくつか実行してみます。
GitHub Actions 検証のために育てているリポジトリを使用します。

$ act --list
Stage  Job ID                    Job name                  Workflow name                            Workflow file                                  Events                                                
0      build                     build                     Azure App Service Settings               azure-app-service-settings.yml                 workflow_dispatch                                     
0      deploy                    deploy                    Azure App Service Swap                   azure-app-service-swap.yml                     workflow_dispatch                                     
0      az_login_with_oidc        az_login_with_oidc        Az CLI Login using OIDC                  azure-az-login-using-oidc.yml                  workflow_dispatch                                     
0      az_login                  az_login                  Az CLI Login using service principal     azure-az-login.yml                             workflow_dispatch                                     
0      connect_to_azure_sql      connect_to_azure_sql      Azure SQL using Connection String        azure-sql-using-conn-string.yml                workflow_dispatch                                     
0      build                     build                     Build Nginx Image                        docker-build-nginx.yml                         workflow_dispatch                                     
0      build                     build                     Publish Express Image to ghcr.io         docker-publish-to-ghcr-express.yml             workflow_dispatch                                     
0      build                     build                     Publish Nginx Image to ghcr.io           docker-publish-to-ghcr-nginx.yml               workflow_dispatch                                     
0      dump                      dump                      GitHub Actions Context Dump              github-actions-context-dump.yml                workflow_call,workflow_dispatch                       
0      build                     build                     GitHub Actions Job Summaries             github-actions-job-summaries.yml               workflow_dispatch                                     
0      build                     build                     GitHub CLI List Repos                    github-cli-list-repos.yml                      workflow_dispatch                                     
0      create_issue              create_issue              GitHub Issue Creation using GitHub CLI   github-issue-creatation-using-gh.yml           workflow_dispatch                                     
0      create_issue              create_issue              GitHub Issue Creation using Marketplace  github-issue-creatation-using-marketplace.yml  workflow_dispatch                                     
0      greet                     greet                     Manual workflow                          manual.yml                                     workflow_dispatch                                     
0      build-aspnetcore6-cached  build-aspnetcore6-cached  ASP.NET Core 6.0 (Cached)                net60-aspnetcore-cached.yml                    push,workflow_dispatch                                
0      build-aspnetcore6         build-aspnetcore6         ASP.NET Core 6.0                         net60-aspnetcore.yml                           push,workflow_dispatch                                
0      build                     build                     ASP.NET Core 7.0                         net70-aspnetcore.yml                           workflow_dispatch,push                                
0      build                     build                     Nodejs Express with Zip                  node-express-with-zip.yml                      push,workflow_dispatch                                
0      build                     build                     Nodejs Express without Artifact          node-express-without-artifact.yml              push,workflow_dispatch                                
0      build                     build                     Nodejs Express                           node-express.yml                               push,workflow_dispatch                                
0      build                     build                     Nodejs NuxtJS on App Service with Zip    node-nuxtjs-on-azure-app-service-with-zip.yml  push,workflow_dispatch                                
0      build                     build                     Nodejs NuxtJS on App Service             node-nuxtjs-on-azure-app-service.yml           workflow_dispatch,push                                
0      build_and_deploy_job      Build and Deploy Job      Nodejs NuxtJS                            node-nuxtjs.yml                                push,workflow_dispatch                                
0      close_pull_request_job    Close Pull Request Job    Nodejs NuxtJS                            node-nuxtjs.yml                                push,workflow_dispatch                                
0      notify                    notify                    Notify to Teams                          notify-to-teams.yml                            workflow_dispatch                                     
0      build                     build                     PHP Laravel                              php-laravel.yml                                push,workflow_dispatch                                
0      build                     build                     PHP Simple                               php-simple.yml                                 push,workflow_dispatch                                
0      build                     build                     Python Django                            python-django.yml                              workflow_dispatch,push                                
0      build                     build                     Python FastAPI                           python-fastapi.yml                             push,workflow_dispatch                                
0      discussion_comment        discussion_comment        Various triggers workflow                various-triggers.yml                           workflow_dispatch,issues,discussion,discussion_comment
0      dump                      dump                      Various triggers workflow                various-triggers.yml                           discussion_comment,workflow_dispatch,issues,discussion
0      issue                     issue                     Various triggers workflow                various-triggers.yml                           issues,discussion,discussion_comment,workflow_dispatch
0      discussion                discussion                Various triggers workflow                various-triggers.yml                           issues,discussion,discussion_comment,workflow_dispatch
0      on-success                on-success                Workflow trigger child                   workflow-trigger-child.yml                     workflow_run                                          
0      on-failure                on-failure                Workflow trigger child                   workflow-trigger-child.yml                     workflow_run                                          
0      build                     build                     Workflow trigger parent                  workflow-trigger-parent.yml                    workflow_dispatch                                     
1      deploy                    deploy                    ASP.NET Core 6.0                         net60-aspnetcore.yml                           workflow_dispatch,push                                
1      deploy                    deploy                    ASP.NET Core 7.0                         net70-aspnetcore.yml                           push,workflow_dispatch                                
1      deploy                    deploy                    Nodejs Express with Zip                  node-express-with-zip.yml                      push,workflow_dispatch                                
1      deploy                    deploy                    Nodejs Express                           node-express.yml                               push,workflow_dispatch                                
1      deploy                    deploy                    Nodejs NuxtJS on App Service with Zip    node-nuxtjs-on-azure-app-service-with-zip.yml  workflow_dispatch,push                                
1      deploy                    deploy                    Nodejs NuxtJS on App Service             node-nuxtjs-on-azure-app-service.yml           push,workflow_dispatch                                
1      deploy                    deploy                    PHP Laravel                              php-laravel.yml                                push,workflow_dispatch                                
1      deploy                    deploy                    PHP Simple                               php-simple.yml                                 push,workflow_dispatch                                
1      deploy                    deploy                    Python Django                            python-django.yml                              push,workflow_dispatch                                
1      deploy                    deploy                    Python FastAPI                           python-fastapi.yml                             workflow_dispatch,push                                

まー、たくさんありますね。ジョブの一覧を見ることができます。

コンテキストを見る

ワークフローのコンテキストをダンプしてみましょう。
コンテキストを見ると、ワークフローの実行者(actor)が nektos/act であることが分かります。

$ act --job dump
[GitHub Actions Context Dump/dump] 🚀  Start image=catthehacker/ubuntu:act-latest
[Various triggers workflow/dump  ] 🚀  Start image=catthehacker/ubuntu:act-latest
[GitHub Actions Context Dump/dump]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=false
[Various triggers workflow/dump  ]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=false
[GitHub Actions Context Dump/dump]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[Various triggers workflow/dump  ]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[GitHub Actions Context Dump/dump]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[Various triggers workflow/dump  ]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[GitHub Actions Context Dump/dump] ⭐ Run Main Dump GitHub context
[Various triggers workflow/dump  ] ⭐ Run Main Dump context
[GitHub Actions Context Dump/dump]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/github_context_step] user= workdir=
[Various triggers workflow/dump  ]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0] user= workdir=
| {
|   "event": {
|     "repository": {
|       "default_branch": "master"
|     }
|   },
| {
|   event: {
|     repository: {
|       default_branch: master
|     }
|   },
|   event_path: /var/run/act/workflow/event.json,
|   workflow: Various triggers workflow,
|   run_id: 1,
|   run_number: 1,
|   actor: nektos/act,
|   repository: tsubakimoto/github-actions-samples,
|   event_name: push,
|   sha: 4cd3e2fe1f2671f9d355cf4226bc021771775b36,
|   ref: refs/heads/main,
|   ref_name: main,
|   ref_type: branch,
|   head_ref: ,
|   base_ref: ,
|   token: ,
|   workspace: /workspaces/github-actions-samples,
|   action: 0,
|   action_path: ,
|   action_ref: ,
|   action_repository: ,
|   job: ,
|   job_name: ,
|   repository_owner: tsubakimoto,
|   retention_days: 0,
|   runner_perflog: /dev/null,
|   runner_tracking_id: 
| }
|   "event_path": "/var/run/act/workflow/event.json",
|   "workflow": "GitHub Actions Context Dump",
|   "run_id": "1",
|   "run_number": "1",
|   "actor": "nektos/act",
|   "repository": "tsubakimoto/github-actions-samples",
|   "event_name": "push",
|   "sha": "4cd3e2fe1f2671f9d355cf4226bc021771775b36",
|   "ref": "refs/heads/main",
|   "ref_name": "main",
|   "ref_type": "branch",
|   "head_ref": "",
|   "base_ref": "",
|   "token": "",
|   "workspace": "/workspaces/github-actions-samples",
|   "action": "github_context_step",
|   "action_path": "",
|   "action_ref": "",
|   "action_repository": "",
|   "job": "",
|   "job_name": "",
|   "repository_owner": "tsubakimoto",
|   "retention_days": "0",
|   "runner_perflog": "/dev/null",
|   "runner_tracking_id": ""
| }
[GitHub Actions Context Dump/dump]   ✅  Success - Main Dump GitHub context
[Various triggers workflow/dump  ]   ✅  Success - Main Dump context
[Various triggers workflow/dump  ] 🏁  Job succeeded
[GitHub Actions Context Dump/dump] 🏁  Job succeeded

.NET アプリをビルドする

次に .NET のアプリケーションをビルドしてみます。
ワークフローの構成はこちらを参照してください。

SDK のインストール、プロジェクトのリストア・ビルド・テスト、いずれも問題なく実行できているようです。

$ act --job build-aspnetcore6
[ASP.NET Core 6.0/build-aspnetcore6] 🚀  Start image=catthehacker/ubuntu:act-latest
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=false
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[ASP.NET Core 6.0/build-aspnetcore6]   ☁  git clone 'https://github.com/actions/setup-dotnet' # ref=v3
[ASP.NET Core 6.0/build-aspnetcore6]   ☁  git clone 'https://github.com/actions/upload-artifact' # ref=v2
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main actions/checkout@v2
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker cp src=/workspaces/github-actions-samples/. dst=/workspaces/github-actions-samples
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main actions/checkout@v2
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Setup .NET
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker cp src=/home/vscode/.cache/act/actions-setup-dotnet@v3/ dst=/var/run/act/actions/actions-setup-dotnet@v3/
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[node /var/run/act/actions/actions-setup-dotnet@v3/dist/index.js] user= workdir=
| [command]/run/act/actions/actions-setup-dotnet@v3/externals/install-dotnet.sh --channel 6.0
| dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
| dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
| dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs.
| dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.
| 
| dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-x64.tar.gz
| dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-x64.tar.gz
| dotnet-install: Installed version is 6.0.403
| dotnet-install: Adding to current process PATH: `/usr/share/dotnet`. Note: This change will be visible only when sourcing script.
| dotnet-install: Note that the script does not resolve dependencies during installation.
| dotnet-install: To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
| dotnet-install: Installation finished successfully.
[ASP.NET Core 6.0/build-aspnetcore6]   ❓  ##[add-matcher]/run/act/actions/actions-setup-dotnet@v3/.github/csc.json
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main Setup .NET
[ASP.NET Core 6.0/build-aspnetcore6]   ⚙  ::set-output:: dotnet-version=6.0.403
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main echo '6.0.403'
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/2] user= workdir=dotnet/net6.0
| 6.0.403
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main echo '6.0.403'
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Restore dependencies
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/3] user= workdir=dotnet/net6.0
| 
| Welcome to .NET 6.0!
| ---------------------
| SDK Version: 6.0.403
| 
| Telemetry
| ---------
| The .NET tools collect usage data in order to help us improve your experience. It is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.
| 
| Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry
| 
| ----------------
| Installed an ASP.NET Core HTTPS development certificate.
| To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
| Learn about HTTPS: https://aka.ms/dotnet-https
| ----------------
| Write your first app: https://aka.ms/dotnet-hello-world
| Find out what's new: https://aka.ms/dotnet-whats-new
| Explore documentation: https://aka.ms/dotnet-docs
| Report issues and find source on GitHub: https://github.com/dotnet/core
| Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
| --------------------------------------------------------------------------------------
|   Determining projects to restore...
|   Restored /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj (in 95 ms).
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main Restore dependencies
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Build
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/4] user= workdir=dotnet/net6.0
| MSBuild version 17.3.2+561848881 for .NET
|   razorpageapp -> /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/bin/Release/net6.0/razorpageapp.dll
| 
| Build succeeded.
|     0 Warning(s)
|     0 Error(s)
| 
| Time Elapsed 00:00:07.82
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main Build
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Publish
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/5] user= workdir=dotnet/net6.0
| MSBuild version 17.3.2+561848881 for .NET
|   razorpageapp -> /usr/share/dotnet/myapp/
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main Publish
[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Upload artifact for deployment job
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker cp src=/home/vscode/.cache/act/actions-upload-artifact@v2/ dst=/var/run/act/actions/actions-upload-artifact@v2/
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[node /var/run/act/actions/actions-upload-artifact@v2/dist/index.js] user= workdir=
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::followSymbolicLinks 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::implicitDescendants 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::omitBrokenSymbolicLinks 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::followSymbolicLinks 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::implicitDescendants 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::omitBrokenSymbolicLinks 'true'
[ASP.NET Core 6.0/build-aspnetcore6]   💬  ::debug::Search path '/myapp'
[ASP.NET Core 6.0/build-aspnetcore6]   🚧  ::warning::No files were found with the provided path: /myapp. No artifacts will be uploaded.
[ASP.NET Core 6.0/build-aspnetcore6]   ✅  Success - Main Upload artifact for deployment job
[ASP.NET Core 6.0/build-aspnetcore6] 🏁  Job succeeded

ビルドエラーはこのように出力されます。

[ASP.NET Core 6.0/build-aspnetcore6] ⭐ Run Main Build
[ASP.NET Core 6.0/build-aspnetcore6]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/4] user= workdir=dotnet/net6.0
| MSBuild version 17.3.2+561848881 for .NET
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(1,49): error CS1003: Syntax error, ',' expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(4,32): error CS1002: ; expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(4,32): error CS1022: Type or namespace definition, or end-of-file expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
| 
| Build FAILED.
| 
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(1,49): error CS1003: Syntax error, ',' expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(4,32): error CS1002: ; expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
| /workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/Program.cs(4,32): error CS1022: Type or namespace definition, or end-of-file expected [/workspaces/github-actions-samples/dotnet/net6.0/razorpageapp/razorpageapp.csproj]
|     0 Warning(s)
|     3 Error(s)
| 
| Time Elapsed 00:00:05.99
[ASP.NET Core 6.0/build-aspnetcore6]   ❌  Failure - Main Build
[ASP.NET Core 6.0/build-aspnetcore6] exitcode '1': failure
[ASP.NET Core 6.0/build-aspnetcore6] 🏁  Job failed
Error: Job 'build-aspnetcore6' failed

Azure CLI を動かす

次に Azure CLI を使って、Azure にログインするワークフローを試します。
GitHub Actions から Azure に接続する場合、通常のサービスプリンシパルで認証する方法と、OIDC で認証する方法があります。
詳しくはこちらのドキュメントを参照してください。

learn.microsoft.com

GitHub Actions なら OIDC 一択ですが、nektos/act では OIDC は使えないためサービスプリンシパルで接続することとなります。
はじめ、方法が分かりませんでしたが、こちらのリポジトリを参考に実現することができました。

github.com

jobs:
  az_login:
    runs-on: ubuntu-latest

    steps:
      - name: Install Azure CLI
        if: github.actor == 'nektos/act'
        shell: bash
        run: |
          curl -sL https://aka.ms/InstallAzureCLIDeb | bash

      - name: Azure Login
        uses: Azure/login@v1
        with:
          creds: ${{secrets.AZURE_CREDENTIALS}}

      - name: Show Azure regions
        run: az account list-locations 

      - name: Az CLI Logout
        run: az logout

ここで actornektos/act の場合に限り、Azure CLI を独自にインストールすることで az コマンドを使用することができます。
なお AZURE_CREDENTIALS というシークレットが必要であるため、ファイルを用意しておきます。

$ act --job az_login --secret-file act/.secrets
[Az CLI Login using service principal/az_login] 🚀  Start image=catthehacker/ubuntu:act-latest
[Az CLI Login using service principal/az_login]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=false
[Az CLI Login using service principal/az_login]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[Az CLI Login using service principal/az_login]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[Az CLI Login using service principal/az_login]   ☁  git clone 'https://github.com/Azure/login' # ref=v1
[Az CLI Login using service principal/az_login] ⭐ Run Main Install Azure CLI
[Az CLI Login using service principal/az_login]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0.sh] user= workdir=
[Az CLI Login using service principal/az_login]   | Get:1 https://packages.microsoft.com/ubuntu/22.04/prod jammy InRelease [10.5 kB]
[Az CLI Login using service principal/az_login]   | Get:2 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages [64.9 kB]
[Az CLI Login using service principal/az_login]   | Get:3 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]

(中略)

[Az CLI Login using service principal/az_login] ⭐ Run Main Azure Login
[Az CLI Login using service principal/az_login]   🐳  docker cp src=/home/vscode/.cache/act/Azure-login@v1/ dst=/var/run/act/actions/Azure-login@v1/
[Az CLI Login using service principal/az_login]   🐳  docker exec cmd=[node /var/run/act/actions/Azure-login@v1/lib/main.js] user= workdir=
[Az CLI Login using service principal/az_login]   💬  ::debug::az cli version used: /usr/bin/az
[Az CLI Login using service principal/az_login]   💬  ::debug::az cli version used:%0Aazure-cli                         2.43.0%0A%0Acore                              2.43.0%0Atelemetry                          1.0.8%0A%0ADependencies:%0Amsal                              1.20.0%0Aazure-mgmt-resource             21.1.0b1%0A%0APython location '/opt/az/bin/python3'%0AExtensions directory '/root/.azure/cliextensions'%0A%0APython (Linux) 3.10.8 (main, Dec  2 2022, 06:07:57) [GCC 11.3.0]%0A%0ALegal docs and information: aka.ms/AzureCliLegal%0A%0A%0AYour CLI is up-to-date.%0A
[Az CLI Login using service principal/az_login]   💬  ::debug::using creds JSON...
[Az CLI Login using service principal/az_login]   ⚙  ***
[Az CLI Login using service principal/az_login]   ⚙  ***
[Az CLI Login using service principal/az_login]   ⚙  ***
[Az CLI Login using service principal/az_login]   ⚙  ***
[Az CLI Login using service principal/az_login]   | [command]/usr/bin/az cloud set -n azurecloud
[Az CLI Login using service principal/az_login]   | Done setting cloud: "azurecloud"
[Az CLI Login using service principal/az_login]   | Note: Azure/login action also supports OIDC login mechanism. Refer https://github.com/azure/login#configure-a-service-principal-with-a-federated-credential-to-use-oidc-based-authentication for more details.
[Az CLI Login using service principal/az_login]   | Login successful.
[Az CLI Login using service principal/az_login]   ✅  Success - Main Azure Login
[Az CLI Login using service principal/az_login] ⭐ Run Main Show Azure regions
[Az CLI Login using service principal/az_login]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/2] user= workdir=
[Az CLI Login using service principal/az_login]   | [
[Az CLI Login using service principal/az_login]   |   {
[Az CLI Login using service principal/az_login]   |     "displayName": "East US",
[Az CLI Login using service principal/az_login]   |     "id": "/subscriptions/***/locations/eastus",
[Az CLI Login using service principal/az_login]   |     "metadata": {
[Az CLI Login using service principal/az_login]   |       "geographyGroup": "US",
[Az CLI Login using service principal/az_login]   |       "latitude": "37.3719",
[Az CLI Login using service principal/az_login]   |       "longitude": "-79.8164",
[Az CLI Login using service principal/az_login]   |       "pairedRegion": [
[Az CLI Login using service principal/az_login]   |         {
[Az CLI Login using service principal/az_login]   |           "id": "/subscriptions/***/locations/westus",
[Az CLI Login using service principal/az_login]   |           "name": "westus",
[Az CLI Login using service principal/az_login]   |           "subscriptionId": null
[Az CLI Login using service principal/az_login]   |         }
[Az CLI Login using service principal/az_login]   |       ],
[Az CLI Login using service principal/az_login]   |       "physicalLocation": "Virginia",
[Az CLI Login using service principal/az_login]   |       "regionCategory": "Recommended",
[Az CLI Login using service principal/az_login]   |       "regionType": "Physical"
[Az CLI Login using service principal/az_login]   |     },
[Az CLI Login using service principal/az_login]   |     "name": "eastus",
[Az CLI Login using service principal/az_login]   |     "regionalDisplayName": "(US) East US",
[Az CLI Login using service principal/az_login]   |     "subscriptionId": null
[Az CLI Login using service principal/az_login]   |   },

(中略)

devcontainer 定義を作成する

nektos/act はコンテナー環境で動作するということで、これは devcontainer の出番です。
devcontainer 自体がコンテナーで動きますが、Docker in Docker を構成することができるため、nektos/act を動かすこともできます。

devcontainer.json はこのように構成します。

{
    "name": "Docker in Docker",
    "image": "mcr.microsoft.com/devcontainers/base:bullseye",
    "features": {
        "ghcr.io/devcontainers/features/common-utils:1": {
            "installZsh": "true",
            "upgradePackages": "false",
            "uid": "1000",
            "gid": "1000",
            "installOhMyZsh": "true",
            "nonFreePackages": "true"
        },
        "ghcr.io/devcontainers/features/docker-in-docker:2": {
            "version": "latest",
            "enableNonRootDocker": "true",
            "moby": "true"
        },
        "ghcr.io/dhoeric/features/act:1": {}
    }
}

github.com

devcontainer 定義が作成できたということは、当然 GitHub Codespaces で動きます!
リポジトリ画面から Codespace を起動しましょう。これで、ブラウザだけで nektos/act によるワークフロー実装を行えるようになりました。


GitHub Actions 環境と全く一緒ではないでしょうが、GitHub Actions のデバッグをすべてオンラインでやるのは大変なので、こういったツールで少しでも効率化したいですね。