├── .github ├── CODEOWNERS ├── actions │ ├── container-build │ │ └── action.yml │ ├── container-deploy │ │ └── action.yml │ ├── dump │ │ └── action.yml │ └── hello │ │ └── action.yml ├── dependabot-ignore.yml ├── dependabot.yml ├── release-exclude.yml ├── release.yml ├── scripts │ ├── bump.sh │ └── token.sh └── workflows │ ├── add-mask.yml │ ├── annotation.yml │ ├── artifacts.yml │ ├── auto-cancel.yml │ ├── auto-merge.yml │ ├── auto-patch-merge.yml │ ├── bash-tracing.yml │ ├── cache.yml │ ├── call.yml │ ├── change-shell.yml │ ├── comment.yml │ ├── compare-functions.yml │ ├── concurrency.yml │ ├── conditions-workflow.yml │ ├── conditions.yml │ ├── conftest.yml │ ├── container-image-scan.yml │ ├── contexts.yml │ ├── continue-on-error.yml │ ├── convert.yml │ ├── cross-repo.yml │ ├── debug-log.yml │ ├── deploy.yml │ ├── dump.yml │ ├── dynamic-matrix.yml │ ├── environment-variables.yml │ ├── environments.yml │ ├── fail-fast-matrix.yml │ ├── flow-control.yml │ ├── generate-functions.yml │ ├── github-env.yml │ ├── github-output.yml │ ├── hash-functions.yml │ ├── hello.yml │ ├── intermediate-environment-variables.yml │ ├── invalid.yml │ ├── job-summaries.yml │ ├── json-functions.yml │ ├── literals.yml │ ├── log-group.yml │ ├── manual-matrix.yml │ ├── manual.yml │ ├── matrix.yml │ ├── missing-share-data.yml │ ├── modified-cross-repo.yml │ ├── multi-dimension-matrix.yml │ ├── naming.yml │ ├── old.yml │ ├── openid-connect.yml │ ├── override-environment-variables.yml │ ├── parallel-jobs.yml │ ├── prevent-security-misconfigurations.yml │ ├── publish.yml │ ├── release-action.yml │ ├── release.yml │ ├── reusable-inherit.yml │ ├── reusable-workflows.yml │ ├── run-name.yml │ ├── schedule.yml │ ├── secret-scan.yml │ ├── secrets.yml │ ├── sequential-jobs.yml │ ├── share-job-data.yml │ ├── static-analysis.yml │ ├── static-application-security-testing.yml │ ├── status-check-functions.yml │ ├── test-action.yml │ ├── test.yml │ ├── timeout.yml │ ├── variables.yml │ ├── workflow-error.yml │ └── yaml-error.yml ├── .go-version ├── CODEOWNERS ├── CODEOWNERS.simple ├── LICENSE ├── README.md ├── action.yml ├── command ├── 11 │ └── README.md └── 12 │ └── README.md ├── docker ├── ecs │ └── Dockerfile └── example │ └── Dockerfile ├── go ├── example │ └── main.go └── excellent │ ├── main.go │ └── main_test.go └── policy └── workflow.rego /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @tmknom 2 | -------------------------------------------------------------------------------- /.github/actions/container-build/action.yml: -------------------------------------------------------------------------------- 1 | name: Container Build 2 | description: コンテナイメージをビルドし、ECRへプッシュします。 3 | inputs: 4 | ecr-repository-uri: 5 | required: true 6 | description: ECRリポジトリのURI 7 | dockerfile-path: 8 | required: true 9 | description: Dockerfileのパス 10 | outputs: 11 | container-image: 12 | value: ${{ steps.meta.outputs.tags }} 13 | description: ビルドしたコンテナイメージ 14 | runs: 15 | using: composite 16 | steps: 17 | - uses: aws-actions/amazon-ecr-login@v2 # Amazon ECRへのログイン 18 | - uses: docker/metadata-action@v5 # コンテナイメージのメタデータ生成 19 | id: meta 20 | with: 21 | images: ${{ inputs.ecr-repository-uri }} 22 | tags: type=sha,format=long 23 | - uses: docker/build-push-action@v5 # コンテナイメージのビルドとプッシュ 24 | with: 25 | push: true 26 | context: ${{ inputs.dockerfile-path }} 27 | tags: ${{ steps.meta.outputs.tags }} 28 | labels: ${{ steps.meta.outputs.labels }} 29 | -------------------------------------------------------------------------------- /.github/actions/container-deploy/action.yml: -------------------------------------------------------------------------------- 1 | name: Container Deploy 2 | description: ECSサービスを更新し、コンテナをデプロイします。 3 | inputs: 4 | ecs-cluster: 5 | required: true 6 | description: ECSクラスター 7 | ecs-service: 8 | required: true 9 | description: ECSサービス 10 | task-definition: 11 | required: true 12 | description: タスク定義 13 | container-name: 14 | required: true 15 | description: コンテナ名 16 | container-image: 17 | required: true 18 | description: コンテナイメージ 19 | runs: 20 | using: composite 21 | steps: 22 | - run: | # タスク定義の取得 23 | aws ecs describe-task-definition --task-definition "${TASK_DEFINITION}" \ 24 | --query taskDefinition --output json > "${RUNNER_TEMP}/task-def.json" 25 | env: 26 | TASK_DEFINITION: ${{ inputs.task-definition }} 27 | shell: bash 28 | - uses: aws-actions/amazon-ecs-render-task-definition@v1 # タスク定義の修正 29 | id: render 30 | with: 31 | task-definition: ${{ runner.temp }}/task-def.json 32 | container-name: ${{ inputs.container-name }} 33 | image: ${{ inputs.container-image }} 34 | - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 # ECSサービスの更新 35 | with: 36 | cluster: ${{ inputs.ecs-cluster }} 37 | service: ${{ inputs.ecs-service }} 38 | task-definition: ${{ steps.render.outputs.task-definition }} 39 | -------------------------------------------------------------------------------- /.github/actions/dump/action.yml: -------------------------------------------------------------------------------- 1 | name: Dump # アクション名 2 | description: | # アクションの概要 3 | 環境変数とgithubコンテキストをログへ出力します。 4 | ワークフローのデバッグに便利です。 5 | inputs: # アクションの入力 6 | enable-context: 7 | default: 'true' 8 | required: false 9 | description: コンテキストをログ出力するか 10 | outputs: # アクションの出力 11 | dumped-date: 12 | value: ${{ steps.current.outputs.date }} 13 | description: ダンプ日時 14 | runs: 15 | using: composite # アクションの実装方式 16 | steps: # アクションのメインロジック 17 | - run: printenv | sort 18 | shell: bash 19 | - run: echo "${CONTEXT}" 20 | if: ${{ inputs.enable-context == 'true' }} 21 | env: 22 | CONTEXT: ${{ toJSON(github) }} 23 | shell: bash 24 | - id: current 25 | run: echo "date=$(date)" >> "${GITHUB_OUTPUT}" 26 | shell: bash 27 | -------------------------------------------------------------------------------- /.github/actions/hello/action.yml: -------------------------------------------------------------------------------- 1 | name: Hello 2 | description: ローカルアクション 3 | runs: 4 | using: composite 5 | steps: 6 | - run: echo "Hello" 7 | shell: bash 8 | -------------------------------------------------------------------------------- /.github/dependabot-ignore.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | ignore: # バージョンアップの除外設定 8 | - dependency-name: actions/upload-artifact # 除外する依存関係の名前 9 | versions: # 除外対象のバージョン 10 | - 4.3.0 11 | - 4.3.1 12 | - dependency-name: 'actions/*' # アスタリスクは任意文字列にマッチ 13 | update-types: # 除外するバージョンアップの種類 14 | - version-update:semver-major 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions # パッケージエコシステム 4 | directory: / # パッケージマニフェストの配置先ディレクトリ 5 | schedule: # バージョンアップスケジュール 6 | interval: daily 7 | -------------------------------------------------------------------------------- /.github/release-exclude.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: 3 | - title: Enhancement 4 | labels: 5 | - enhancement 6 | exclude: # リリースノートの除外設定 7 | labels: # 除外するラベル 8 | - dependencies 9 | authors: # 除外するプルリクエスト作成者 10 | - dependabot 11 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: # リリースノートのカテゴリ設定 3 | - title: Enhancement # リリースノートへ「Enhancement」というカテゴリを作成する 4 | labels: 5 | - enhancement # 「Enhancement」へ掲載するプルリクエストのラベルを指定する 6 | - title: Bug Fixes 7 | labels: # プルリクエストのラベルは複数定義できる 8 | - bug 9 | - fixes 10 | -------------------------------------------------------------------------------- /.github/scripts/bump.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # GitHubからGitタグをまとめてフェッチして、最新バージョンを取り出す 4 | git fetch --tag 2>/dev/null 5 | version="$(git tag --sort=-v:refname | head -1 | sed 's/^v//')" 6 | 7 | # 指定されたバージョンアップレベルに基づいて、新しいバージョンを算出 8 | IFS='.' read -ra tokens <<<"${version:-0.0.0}" 9 | major="${tokens[0]}"; minor="${tokens[1]}"; patch="${tokens[2]}" 10 | case "$1" in 11 | major) major="$((major + 1))"; minor=0; patch=0 ;; 12 | minor) minor="$((minor + 1))"; patch=0 ;; 13 | patch) patch="$((patch + 1))" ;; 14 | esac 15 | 16 | # GitHubへフルバージョンタグとメジャーバージョンタグをプッシュ 17 | git tag "v${major}.${minor}.${patch}" 18 | git tag --force "v${major}" >/dev/null 2>&1 19 | git push --force --tags >/dev/null 2>&1 20 | echo "v${major}.${minor}.${patch}" 21 | -------------------------------------------------------------------------------- /.github/scripts/token.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base64url() { 4 | openssl enc -base64 -A | tr '+/' '-_' | tr -d '=' 5 | } 6 | 7 | sign() { 8 | openssl dgst -binary -sha256 -sign <(printf '%s' "${PRIVATE_KEY}") 9 | } 10 | 11 | # JWTの生成 12 | header="$(printf '{"alg":"RS256","typ":"JWT"}' | base64url)" 13 | now="$(date '+%s')" 14 | iat="$((now - 60))" 15 | exp="$((now + (3 * 60)))" 16 | template='{"iss":"%s","iat":%s,"exp":%s}' 17 | payload="$(printf "${template}" "${APP_ID}" "${iat}" "${exp}" | base64url)" 18 | signature="$(printf '%s' "${header}.${payload}" | sign | base64url)" 19 | jwt="${header}.${payload}.${signature}" 20 | 21 | # Installation APIの実行 22 | repo="${GITHUB_REPOSITORY_OWNER}/${TARGET_REPO}" 23 | installation_id="$(curl --location --silent --request GET \ 24 | --url "${GITHUB_API_URL}/repos/${repo}/installation" \ 25 | --header "Accept: application/vnd.github+json" \ 26 | --header "X-GitHub-Api-Version: 2022-11-28" \ 27 | --header "Authorization: Bearer ${jwt}" \ 28 | | jq -r '.id' 29 | )" 30 | 31 | # Access Tokens APIの実行 32 | token="$(curl --location --silent --request POST \ 33 | --url "${GITHUB_API_URL}/app/installations/${installation_id}/access_tokens" \ 34 | --header "Accept: application/vnd.github+json" \ 35 | --header "X-GitHub-Api-Version: 2022-11-28" \ 36 | --header "Authorization: Bearer ${jwt}" \ 37 | --data "$(printf '{"repositories":["%s"]}' "${TARGET_REPO}")" \ 38 | | jq -r '.token' 39 | )" 40 | echo "token=${token}" >>"${GITHUB_OUTPUT}" 41 | -------------------------------------------------------------------------------- /.github/workflows/add-mask.yml: -------------------------------------------------------------------------------- 1 | name: Add mask 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | env: 7 | PASSWORD: SuperSecretValue 8 | steps: 9 | - run: echo "::add-mask::${PASSWORD}" # ログ出力時にマスク 10 | - run: echo "${PASSWORD}" 11 | -------------------------------------------------------------------------------- /.github/workflows/annotation.yml: -------------------------------------------------------------------------------- 1 | name: Annotation 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "::error::This is an error" # Errorレベルのアノテーション 8 | - run: echo "::warning::This is a warning" # Warningレベルのアノテーション 9 | - run: echo "::notice::This is a notice" # Noticeレベルのアノテーション 10 | -------------------------------------------------------------------------------- /.github/workflows/artifacts.yml: -------------------------------------------------------------------------------- 1 | name: Artifacts 2 | on: push 3 | jobs: 4 | upload: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: date > date.txt # アーティファクトの生成 8 | - uses: actions/upload-artifact@v4 # アーティファクトのアップロード 9 | with: 10 | name: uploaded # アーティファクト名 11 | path: date.txt # アップロード対象のパス 12 | retention-days: 7 # アーティファクトの保存期間 13 | download: 14 | runs-on: ubuntu-latest 15 | needs: [upload] # uploadジョブの実行を待つ 16 | steps: 17 | - uses: actions/download-artifact@v4 # アーティファクトのダウンロード 18 | with: 19 | name: uploaded # アーティファクト名 20 | path: downloaded # ダウンロード先のパス 21 | - run: cat downloaded/date.txt # アーティファクトを標準出力 22 | -------------------------------------------------------------------------------- /.github/workflows/auto-cancel.yml: -------------------------------------------------------------------------------- 1 | name: Auto cancel 2 | on: pull_request 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true # 同一グループのワークフローが実行中ならキャンセル 6 | jobs: 7 | sleep: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - run: sleep 120 11 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Auto merge 2 | on: pull_request 3 | jobs: 4 | merge: 5 | if: ${{ github.actor == 'dependabot[bot]' }} # Dependabotのプルリクエストのみ 6 | runs-on: ubuntu-latest 7 | permissions: # マージに必要なパーミッション 8 | contents: write 9 | pull-requests: write 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub CLIのクレデンシャル 12 | steps: 13 | - uses: actions/checkout@v4 14 | - run: gh pr merge "${GITHUB_HEAD_REF}" --merge # GitHub CLIでマージ 15 | -------------------------------------------------------------------------------- /.github/workflows/auto-patch-merge.yml: -------------------------------------------------------------------------------- 1 | name: Auto patch merge 2 | on: pull_request 3 | jobs: 4 | merge: 5 | if: ${{ github.actor == 'dependabot[bot]' }} 6 | runs-on: ubuntu-latest 7 | permissions: 8 | contents: write 9 | pull-requests: write 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | steps: 13 | - uses: actions/checkout@v4 14 | - id: meta # 依存関係のメタデータを取得 15 | uses: dependabot/fetch-metadata@v2 # 条件分岐でパッチバージョンかチェック 16 | - if: ${{ steps.meta.outputs.update-type == 'version-update:semver-patch' }} 17 | run: | 18 | gh pr review "${GITHUB_HEAD_REF}" --approve 19 | gh pr merge "${GITHUB_HEAD_REF}" --merge --auto 20 | -------------------------------------------------------------------------------- /.github/workflows/bash-tracing.yml: -------------------------------------------------------------------------------- 1 | name: Bash tracing 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: | # Bashのトレーシングオプションを有効化し、実行したコマンドをログ出力 8 | set -x 9 | date 10 | hostname 11 | -------------------------------------------------------------------------------- /.github/workflows/cache.yml: -------------------------------------------------------------------------------- 1 | name: Cache 2 | on: push 3 | jobs: 4 | cache: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: actions/cache@v4 # キャッシュの復元と保存 9 | with: 10 | key: test-${{ runner.os }}-${{ github.sha }} # キャッシュキー 11 | path: ${{ github.workspace }}/dummy # キャッシュ対象のパス 12 | restore-keys: | # リストアキー 13 | test-${{ runner.os }}- 14 | - run: | 15 | if [[ -f "${GITHUB_WORKSPACE}/dummy" ]]; then exit 0; fi 16 | dd if=/dev/urandom of="${GITHUB_WORKSPACE}/dummy" bs=1M count=10 17 | sleep 30 18 | - run: ls -lh "${GITHUB_WORKSPACE}/dummy" 19 | -------------------------------------------------------------------------------- /.github/workflows/call.yml: -------------------------------------------------------------------------------- 1 | name: Call 2 | on: pull_request 3 | jobs: 4 | call: 5 | uses: ./.github/workflows/reusable-workflows.yml # Reusable Workflowsの指定 6 | with: # 平文の入力パラメータ指定 7 | pr-number: ${{ github.event.pull_request.number }} 8 | secrets: # Secretsの入力パラメータ指定 9 | token: ${{ secrets.GITHUB_TOKEN }} 10 | permissions: 11 | contents: read 12 | pull-requests: write 13 | print: 14 | needs: [call] 15 | runs-on: ubuntu-latest 16 | steps: 17 | - run: echo "Result> ${MESSAGE}" 18 | env: 19 | MESSAGE: ${{ needs.call.outputs.message }} # 出力値の参照 20 | -------------------------------------------------------------------------------- /.github/workflows/change-shell.yml: -------------------------------------------------------------------------------- 1 | name: Change shell 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - shell: bash # シェルにBashを指定 8 | run: echo "${SHELL}" 9 | - shell: python # シェルにPythonを指定 10 | run: | 11 | import os 12 | print(os.environ['PATH']) 13 | -------------------------------------------------------------------------------- /.github/workflows/comment.yml: -------------------------------------------------------------------------------- 1 | name: Comment 2 | on: pull_request 3 | jobs: 4 | comment: 5 | runs-on: ubuntu-latest 6 | permissions: # GITHUB_TOKENの権限を指定 7 | pull-requests: write # プルリクエストの書き込みを許可 8 | contents: read # ソースコードの読み込みを許可 9 | steps: 10 | - uses: actions/checkout@v4 11 | - run: gh pr comment "${GITHUB_HEAD_REF}" --body "Hello, ${GITHUB_ACTOR}" 12 | env: 13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub CLI用クレデンシャル 14 | -------------------------------------------------------------------------------- /.github/workflows/compare-functions.yml: -------------------------------------------------------------------------------- 1 | name: Compare functions 2 | on: push 3 | jobs: 4 | compare: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: printenv | grep '_FUNC' 8 | env: 9 | CONTAINS_FUNC: ${{ contains('Hello', 'ell') }} # 「ell」を含むか 10 | STARTS_WITH_FUNC: ${{ startsWith('Hello', 'He') }} # 「He」で始まるか 11 | ENDS_WITH_FUNC: ${{ endsWith('Hello', 'lo') }} # 「lo」で終わるか 12 | -------------------------------------------------------------------------------- /.github/workflows/concurrency.yml: -------------------------------------------------------------------------------- 1 | name: Concurrency 2 | on: push 3 | concurrency: ${{ github.workflow }} # Concurrencyグループへワークフロー名を指定 4 | jobs: 5 | sleep: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - run: sleep 120 9 | -------------------------------------------------------------------------------- /.github/workflows/conditions-workflow.yml: -------------------------------------------------------------------------------- 1 | name: Conditions workflow 2 | on: push 3 | jobs: 4 | skip-or-run: 5 | if: ${{ github.actor == 'octocat' }} # octocatアカウント以外は実行をスキップ 6 | runs-on: ubuntu-latest 7 | steps: 8 | - run: echo "Hello" 9 | -------------------------------------------------------------------------------- /.github/workflows/conditions.yml: -------------------------------------------------------------------------------- 1 | name: Conditions 2 | on: push 3 | jobs: 4 | skip-or-run: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "Hello" 8 | if: ${{ contains(github.run_id, '1') }} # ワークフロー実行IDで分岐 9 | -------------------------------------------------------------------------------- /.github/workflows/conftest.yml: -------------------------------------------------------------------------------- 1 | name: Conftest 2 | on: pull_request 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - run: | # ポリシーファイルのパスを指定し、Conftestでワークフローファイルを検証 9 | docker run --rm -v "$(pwd):$(pwd)" -w "$(pwd)" \ 10 | openpolicyagent/conftest test --policy policy/ .github/workflows/ 11 | -------------------------------------------------------------------------------- /.github/workflows/container-image-scan.yml: -------------------------------------------------------------------------------- 1 | name: Container image scan 2 | on: pull_request 3 | jobs: 4 | scan: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: aquasecurity/trivy-action@0.19.0 # Trivyの実行 8 | with: 9 | image-ref: nginx:1.11.0 # スキャン対象のコンテナイメージ 10 | severity: CRITICAL,HIGH # レポート対象の重大度 11 | exit-code: 1 # 問題発見時の終了ステータス 12 | -------------------------------------------------------------------------------- /.github/workflows/contexts.yml: -------------------------------------------------------------------------------- 1 | name: Contexts 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "${{ github.actor }}" # githubコンテキストの参照 8 | -------------------------------------------------------------------------------- /.github/workflows/continue-on-error.yml: -------------------------------------------------------------------------------- 1 | name: Continue on Error 2 | on: push 3 | jobs: 4 | failure: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: exit 1 # 終了ステータスがゼロ以外なので、エラーが発生する 8 | continue-on-error: true # Continue on Errorが発生したエラーを握りつぶす 9 | - run: echo "Success" # 素知らぬ顔で実行され、ワークフローは正常終了する 10 | -------------------------------------------------------------------------------- /.github/workflows/convert.yml: -------------------------------------------------------------------------------- 1 | name: Convert 2 | on: push 3 | env: 4 | TIMEOUT: 1 5 | jobs: 6 | sleep: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - run: sleep 120 10 | timeout-minutes: ${{ fromJSON(env.TIMEOUT) }} # string型をnumber型へ変換 11 | -------------------------------------------------------------------------------- /.github/workflows/cross-repo.yml: -------------------------------------------------------------------------------- 1 | name: Cross repo 2 | on: push 3 | env: 4 | TARGET_REPO: another-repo # GitHub Appsのインストール時に設定したリポジトリ 5 | jobs: 6 | checkout: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - id: create # GitHub Appsトークンの生成 10 | uses: actions/create-github-app-token@v1 11 | with: 12 | app-id: ${{ secrets.APP_ID }} 13 | private-key: ${{ secrets.PRIVATE_KEY }} 14 | repositories: ${{ env.TARGET_REPO }} 15 | - uses: actions/checkout@v4 # 別リポジトリのチェックアウト 16 | with: 17 | repository: ${{ github.repository_owner }}/${{ env.TARGET_REPO }} 18 | path: ${{ env.TARGET_REPO }} 19 | token: ${{ steps.create.outputs.token }} 20 | - run: cat "${TARGET_REPO}/README.md" # 別リポジトリのREADMEを表示 21 | -------------------------------------------------------------------------------- /.github/workflows/debug-log.yml: -------------------------------------------------------------------------------- 1 | name: Debug log 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "::debug::This is a debug log" # デバッグログ有効化時にのみ出力 8 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: workflow_dispatch 3 | env: 4 | ROLE_ARN: arn:aws:iam::${{ secrets.AWS_ID }}:role/${{ secrets.ROLE_NAME }} 5 | SESSION_NAME: gh-oidc-${{ github.run_id }}-${{ github.run_attempt }} 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: read 11 | id-token: write 12 | steps: 13 | - uses: actions/checkout@v4 # チェックアウト 14 | - uses: aws-actions/configure-aws-credentials@v4 # 一時クレデンシャルの取得 15 | with: 16 | role-to-assume: ${{ env.ROLE_ARN }} 17 | role-session-name: ${{ env.SESSION_NAME }} 18 | aws-region: ap-northeast-1 19 | - uses: ./.github/actions/container-build/ # コンテナイメージのビルド 20 | id: build 21 | with: 22 | ecr-repository-uri: ${{ vars.ECR_REPOSITORY_URI }} 23 | dockerfile-path: docker/ecs/ 24 | - uses: ./.github/actions/container-deploy/ # コンテナのデプロイ 25 | with: 26 | ecs-cluster: ${{ vars.ECS_CLUSTER_NAME }} 27 | ecs-service: ${{ vars.ECS_SERVICE_NAME }} 28 | task-definition: ${{ vars.TASK_DEFINITION_NAME }} 29 | container-name: ${{ vars.CONTAINER_NAME }} 30 | container-image: ${{ steps.build.outputs.container-image }} 31 | -------------------------------------------------------------------------------- /.github/workflows/dump.yml: -------------------------------------------------------------------------------- 1 | name: Dump 2 | on: push 3 | jobs: 4 | debug: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 # ローカルアクション呼び出し前にチェックアウト 8 | - uses: ./.github/actions/dump/ # ローカルアクションの呼び出し 9 | id: dump # 出力値参照のためステップIDを定義 10 | with: 11 | enable-context: 'true' # 入力パラメータの指定 12 | - run: echo "${DATE}" 13 | env: 14 | DATE: ${{ steps.dump.outputs.dumped-date }} # アクションの出力値を参照 15 | -------------------------------------------------------------------------------- /.github/workflows/dynamic-matrix.yml: -------------------------------------------------------------------------------- 1 | name: Dynamic matrix 2 | on: push 3 | jobs: 4 | prepare: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - id: dynamic 8 | run: | # マトリックス定義をJSON文字列で記述 9 | json='{"runner": ["ubuntu-latest", "macos-latest"]}' 10 | echo "json=${json}" >> "${GITHUB_OUTPUT}" 11 | outputs: # マトリックス定義のJSON文字列をジョブ出力値へセット 12 | matrix-json: ${{ steps.dynamic.outputs.json }} 13 | print: 14 | needs: [prepare] 15 | strategy: # JSON文字列からfromJSON関数で動的にマトリックスを生成 16 | matrix: ${{ fromJSON(needs.prepare.outputs.matrix-json) }} 17 | runs-on: ${{ matrix.runner }} 18 | steps: 19 | - run: echo "${RUNNER_OS}" 20 | -------------------------------------------------------------------------------- /.github/workflows/environment-variables.yml: -------------------------------------------------------------------------------- 1 | name: Environment variables 2 | on: push 3 | jobs: 4 | run: 5 | runs-on: ubuntu-latest 6 | env: 7 | BRANCH: main # ジョブレベルで環境変数を定義 8 | steps: 9 | - run: echo "${BRANCH}" # シェルコマンドからジョブレベルの環境変数を参照 10 | - uses: actions/checkout@v4 11 | with: 12 | ref: ${{ env.BRANCH }} # envコンテキスト経由でジョブレベルの環境変数を参照 13 | -------------------------------------------------------------------------------- /.github/workflows/environments.yml: -------------------------------------------------------------------------------- 1 | name: Environments 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | environment-name: 6 | type: environment # 入力パラメータでEnvironmentsを切り替え 7 | default: test 8 | required: false 9 | description: Environment name 10 | jobs: 11 | print: 12 | runs-on: ubuntu-latest 13 | environment: ${{ inputs.environment-name }} # 利用するEnvironmentsを指定 14 | env: 15 | USERNAME: ${{ vars.USERNAME }} # Environment variablesの参照 16 | PASSWORD: ${{ secrets.PASSWORD }} # Environment secretsの参照 17 | steps: 18 | - run: echo "${USERNAME}" 19 | - run: echo "${PASSWORD:0:1} ${PASSWORD#?}" 20 | -------------------------------------------------------------------------------- /.github/workflows/fail-fast-matrix.yml: -------------------------------------------------------------------------------- 1 | name: Fail-fast matrix 2 | on: push 3 | jobs: 4 | run: 5 | runs-on: ubuntu-latest 6 | strategy: 7 | fail-fast: false # マトリックスのフェイルファストを無効化する 8 | matrix: 9 | time: [10, 20, 30] # ジョブごとに異なる時間スリープさせる 10 | steps: 11 | - run: sleep "${SLEEP_TIME}" && exit 1 12 | env: 13 | SLEEP_TIME: ${{ matrix.time }} 14 | -------------------------------------------------------------------------------- /.github/workflows/flow-control.yml: -------------------------------------------------------------------------------- 1 | name: Flow control 2 | on: push 3 | jobs: 4 | run: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: exit "$(( RANDOM % 2 ))" 8 | - run: exit 1 9 | id: error 10 | - run: echo "Catch error step" 11 | if: ${{ failure() && steps.error.outcome == 'failure' }} 12 | -------------------------------------------------------------------------------- /.github/workflows/generate-functions.yml: -------------------------------------------------------------------------------- 1 | name: Generate functions 2 | on: push 3 | jobs: 4 | generate: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: printenv | grep '_FUNC' 8 | env: 9 | FORMAT_FUNC: ${{ format('{0}, {1}.', 'Hi', 'world') }} # フォーマット 10 | JOIN_FUNC: ${{ join(github.event.*.html_url, ', ') }} # カンマで結合 11 | -------------------------------------------------------------------------------- /.github/workflows/github-env.yml: -------------------------------------------------------------------------------- 1 | name: GITHUB_ENV 2 | on: push 3 | jobs: 4 | share: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "RESULT=hello" >> "${GITHUB_ENV}" # GITHUB_ENVへ書き出し 8 | - run: echo "${RESULT}" # 通常の環境変数として参照 9 | -------------------------------------------------------------------------------- /.github/workflows/github-output.yml: -------------------------------------------------------------------------------- 1 | name: GITHUB_OUTPUT 2 | on: push 3 | jobs: 4 | share: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - id: source # ステップIDを設定 8 | run: echo "result=Hello" >> "${GITHUB_OUTPUT}" # GITHUB_OUTPUTへ書き出し 9 | - env: 10 | RESULT: ${{ steps.source.outputs.result }} # stepsコンテキストから参照 11 | run: echo "${RESULT}" 12 | -------------------------------------------------------------------------------- /.github/workflows/hash-functions.yml: -------------------------------------------------------------------------------- 1 | name: Hash functions 2 | on: push 3 | jobs: 4 | hash: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - run: echo "${HASH}" 9 | env: 10 | HASH: ${{ hashFiles('.github/workflows/*.yml') }} # ハッシュ値の生成 11 | -------------------------------------------------------------------------------- /.github/workflows/hello.yml: -------------------------------------------------------------------------------- 1 | name: Hello # ワークフロー名 2 | on: push # イベント(プッシュ時に起動) 3 | jobs: # ジョブの定義 4 | hello: # ジョブID 5 | runs-on: ubuntu-latest # ランナー(Ubuntuで実行) 6 | steps: # ステップの定義 7 | - run: echo "Hello, world" # シェルコマンドの実行 8 | - uses: actions/checkout@v4 # アクションの呼び出し 9 | -------------------------------------------------------------------------------- /.github/workflows/intermediate-environment-variables.yml: -------------------------------------------------------------------------------- 1 | name: Intermediate environment variables 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | env: 7 | ACTOR: ${{ github.actor }} # コンテキストの値を環境変数へセット 8 | steps: 9 | - run: echo "${ACTOR}" # 環境変数経由でコンテキストのプロパティを参照 10 | -------------------------------------------------------------------------------- /.github/workflows/invalid.yml: -------------------------------------------------------------------------------- 1 | name: Invalid 2 | on: push 3 | -------------------------------------------------------------------------------- /.github/workflows/job-summaries.yml: -------------------------------------------------------------------------------- 1 | name: Job summaries 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: | # マークダウンテキストをジョブサマリーへ出力 8 | echo "## Example Title :rocket:" >> "${GITHUB_STEP_SUMMARY}" 9 | echo "- first line" >> "${GITHUB_STEP_SUMMARY}" 10 | echo "- second line" >> "${GITHUB_STEP_SUMMARY}" 11 | -------------------------------------------------------------------------------- /.github/workflows/json-functions.yml: -------------------------------------------------------------------------------- 1 | name: JSON functions 2 | on: push 3 | jobs: 4 | dump: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: echo "${CONTEXT}" 8 | env: 9 | CONTEXT: ${{ toJSON(github) }} # githubコンテキストをJSON文字列でダンプ 10 | -------------------------------------------------------------------------------- /.github/workflows/literals.yml: -------------------------------------------------------------------------------- 1 | name: Literals 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: printenv | grep 'LITERAL_' 8 | env: 9 | LITERAL_NULL: ${{ null }} # null型 10 | LITERAL_BOOLEAN: ${{ true }} # boolean型 11 | LITERAL_NUMBER: ${{ 1234 }} # number型 12 | LITERAL_STRING: ${{ 'Hello' }} # string型(通常記法) 13 | LITERAL_OMIT_STRING: World # string型(省略記法) 14 | -------------------------------------------------------------------------------- /.github/workflows/log-group.yml: -------------------------------------------------------------------------------- 1 | name: Log group 2 | on: push 3 | jobs: 4 | log: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: | 8 | echo "::group::Show environment variables" # ロググループ化の開始 9 | printenv 10 | echo "::endgroup::" # ロググループ化の終了 11 | -------------------------------------------------------------------------------- /.github/workflows/manual-matrix.yml: -------------------------------------------------------------------------------- 1 | name: Manual matrix 2 | on: push 3 | jobs: 4 | print: 5 | strategy: 6 | matrix: # 多次元マトリックスの定義 7 | include: # 組み合わせ条件を手動で列挙 8 | - os: ubuntu-latest # パターン1 9 | version: 20 10 | - os: macos-latest # パターン2 11 | version: 18 12 | runs-on: ${{ matrix.os }} 13 | steps: 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: ${{ matrix.version }} 17 | - run: echo "${RUNNER_OS}" && node --version 18 | -------------------------------------------------------------------------------- /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | name: Manual 2 | on: 3 | workflow_dispatch: # 手動実行イベント 4 | inputs: 5 | greeting: # 入力パラメータ名 6 | type: string # データ型(文字列) 7 | default: Hello # 入力パラメータのデフォルト値 8 | required: true # 入力パラメータの必須フラグ 9 | description: A cheerful word # 入力パラメータの概要 10 | jobs: 11 | run: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - run: echo "${{ inputs.greeting }}" # 入力パラメータ「greeting」の参照 15 | -------------------------------------------------------------------------------- /.github/workflows/matrix.yml: -------------------------------------------------------------------------------- 1 | name: Matrix 2 | on: push 3 | jobs: 4 | print: 5 | strategy: 6 | matrix: # マトリックスの定義 7 | os: [ubuntu-latest, windows-latest, macos-latest] # osプロパティの定義 8 | runs-on: ${{ matrix.os }} # osプロパティの参照 9 | steps: 10 | - run: echo "${RUNNER_OS}" 11 | shell: bash 12 | -------------------------------------------------------------------------------- /.github/workflows/missing-share-data.yml: -------------------------------------------------------------------------------- 1 | name: Missing share data 2 | on: push 3 | jobs: 4 | share: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: export RESULT="hello" # 次のステップへ環境変数で値を渡そうとしている 8 | - run: echo "${RESULT}" # しかし環境変数を参照しても空文字になる 9 | -------------------------------------------------------------------------------- /.github/workflows/modified-cross-repo.yml: -------------------------------------------------------------------------------- 1 | name: Modified cross repo 2 | on: push 3 | env: 4 | TARGET_REPO: another-repo 5 | jobs: 6 | checkout: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 # スクリプト実行にはチェックアウトが必要 10 | - id: create 11 | run: .github/scripts/token.sh # GitHub Appsトークン生成スクリプトの実行 12 | env: # App IDや秘密鍵は環境変数で渡すことに注意 13 | APP_ID: ${{ secrets.APP_ID }} 14 | PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} 15 | - uses: actions/checkout@v4 16 | with: 17 | repository: ${{ github.repository_owner }}/${{ env.TARGET_REPO }} 18 | path: ${{ env.TARGET_REPO }} 19 | token: ${{ steps.create.outputs.token }} 20 | - run: cat "${TARGET_REPO}/README.md" 21 | -------------------------------------------------------------------------------- /.github/workflows/multi-dimension-matrix.yml: -------------------------------------------------------------------------------- 1 | name: Multi-dimension matrix 2 | on: push 3 | jobs: 4 | print: 5 | strategy: 6 | matrix: # 多次元マトリックスの定義 7 | os: [ubuntu-latest, macos-latest] # osプロパティの定義 8 | version: [18, 20] # versionプロパティの定義 9 | runs-on: ${{ matrix.os }} # osプロパティの参照 10 | steps: 11 | - uses: actions/setup-node@v4 12 | with: 13 | node-version: ${{ matrix.version }} # versionプロパティの参照 14 | - run: echo "${RUNNER_OS}" && node --version 15 | -------------------------------------------------------------------------------- /.github/workflows/naming.yml: -------------------------------------------------------------------------------- 1 | name: Naming 2 | on: push 3 | jobs: 4 | print: 5 | name: Super Useful Job # ジョブ名の指定 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Amazing Script # ステップ名の指定 9 | run: echo "Hello" 10 | -------------------------------------------------------------------------------- /.github/workflows/old.yml: -------------------------------------------------------------------------------- 1 | name: Old 2 | on: workflow_dispatch 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/setup-go@v4 # 古いバージョンを意図的に指定 8 | -------------------------------------------------------------------------------- /.github/workflows/openid-connect.yml: -------------------------------------------------------------------------------- 1 | name: OpenID Connect 2 | on: push 3 | env: # AWSの認証アクションへ指定する入力パラメータを環境変数として定義 4 | ROLE_ARN: arn:aws:iam::${{ secrets.AWS_ID }}:role/${{ secrets.ROLE_NAME }} 5 | SESSION_NAME: gh-oidc-${{ github.run_id }}-${{ github.run_attempt }} 6 | jobs: 7 | connect: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | id-token: write # OIDCトークンの取得を許可 11 | steps: 12 | - uses: aws-actions/configure-aws-credentials@v4 # AWSの認証アクション 13 | with: 14 | role-to-assume: ${{ env.ROLE_ARN }} 15 | role-session-name: ${{ env.SESSION_NAME }} 16 | aws-region: ap-northeast-1 17 | - run: aws iam list-users # 一時クレデンシャルの利用 18 | - run: aws iam create-user --user-name invalid || true 19 | -------------------------------------------------------------------------------- /.github/workflows/override-environment-variables.yml: -------------------------------------------------------------------------------- 1 | name: Override environment variables 2 | on: push 3 | env: 4 | EXAMPLE: Defined by workflow level # ワークフローレベルで環境変数を定義 5 | jobs: 6 | print: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - run: echo "${EXAMPLE}" # ワークフローレベルの環境変数を出力 10 | - env: 11 | EXAMPLE: Defined by step level # ステップレベルで環境変数をオーバーライド 12 | run: echo "${EXAMPLE}" # オーバーライドされた環境変数を出力 13 | -------------------------------------------------------------------------------- /.github/workflows/parallel-jobs.yml: -------------------------------------------------------------------------------- 1 | name: Parallel jobs 2 | on: push 3 | jobs: # jobsキーへ複数のジョブを定義すれば、並列に実行される 4 | first: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: sleep 10 && echo "First job" 8 | second: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - run: sleep 10 && echo "Second job" 12 | third: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - run: sleep 10 && echo "Third job" 16 | -------------------------------------------------------------------------------- /.github/workflows/prevent-security-misconfigurations.yml: -------------------------------------------------------------------------------- 1 | name: Prevent security misconfigurations 2 | on: pull_request 3 | jobs: 4 | scan: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: aquasecurity/trivy-action@0.19.0 # Trivyの実行 9 | with: 10 | scan-type: config # セキュリティ設定ミスの検出 11 | severity: CRITICAL,HIGH # レポート対象の重大度 12 | exit-code: 1 # 問題発見時の終了ステータス 13 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | version: # ワークフロー起動時に指定するバージョン 6 | type: string 7 | required: true 8 | description: バージョン(例:1.2.3) 9 | env: 10 | IMAGE_NAME: gha-image # コンテナイメージ名 11 | jobs: 12 | publish: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | packages: write # GitHub Packagesへの書き込みを許可 16 | contents: read # ソースコードのチェックアウトを許可 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: docker/login-action@v3 # コンテナレジストリへのログイン 20 | with: 21 | registry: ghcr.io 22 | username: ${{ github.actor }} 23 | password: ${{ secrets.GITHUB_TOKEN }} 24 | - uses: docker/metadata-action@v5 # コンテナイメージのメタデータ生成 25 | id: meta 26 | with: 27 | images: ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} 28 | tags: | 29 | type=semver,pattern={{version}},value=v${{ inputs.version }} 30 | type=raw,value=latest 31 | - uses: docker/build-push-action@v5 # コンテナイメージのビルドとプッシュ 32 | with: 33 | push: true 34 | context: docker/example/ 35 | tags: ${{ steps.meta.outputs.tags }} 36 | labels: ${{ steps.meta.outputs.labels }} 37 | -------------------------------------------------------------------------------- /.github/workflows/release-action.yml: -------------------------------------------------------------------------------- 1 | name: Release action 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | bump-level: # バージョニングスクリプトの引数として利用する 6 | type: choice 7 | options: [patch, minor, major] 8 | required: true 9 | description: Bump to patch or minor or major 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | contents: write 15 | steps: 16 | - uses: actions/checkout@v4 17 | - env: 18 | USERNAME: github-actions[bot] 19 | EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 20 | BUMP_LEVEL: ${{ inputs.bump-level }} 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | run: | # バージョニングスクリプトを実行し、リリースノートを生成する 23 | git config --global user.name "${USERNAME}" 24 | git config --global user.email "${EMAIL}" 25 | version="$(.github/scripts/bump.sh "${BUMP_LEVEL}")" 26 | gh release create "${version}" --title "${version}" --generate-notes 27 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: 5 | - 'v[0-9]+.[0-9]+.[0-9]+' # v1.2.3のようなGitタグがプッシュされたら起動 6 | jobs: 7 | release: 8 | runs-on: ubuntu-latest 9 | env: 10 | VERSION: ${{ github.ref_name }} # v1.2.3のような値をGitタグから取得 11 | permissions: 12 | contents: write # リリースノートの作成に必要なパーミッション 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-go@v5 16 | with: 17 | go-version: '1.22' 18 | - run: | # リリース対象アプリケーションのビルド 19 | go build -ldflags "-X main.version=${VERSION}" \ 20 | -o "${RUNNER_TEMP}/example" go/example/main.go 21 | - run: | # リリースノートの作成とアセットのアップロード 22 | gh release create "${VERSION}" --title "${VERSION}" --generate-notes 23 | gh release upload "${VERSION}" "${RUNNER_TEMP}/example" 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/reusable-inherit.yml: -------------------------------------------------------------------------------- 1 | name: Reusable Inherit 2 | on: 3 | workflow_call: 4 | secrets: 5 | token: 6 | required: true 7 | description: GitHubトークン 8 | jobs: 9 | inherit: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - id: pr-comment 14 | run: | 15 | echo "${TOKEN:0:1} ${TOKEN#?}" 16 | env: 17 | TOKEN: ${{ secrets.token }} 18 | -------------------------------------------------------------------------------- /.github/workflows/reusable-workflows.yml: -------------------------------------------------------------------------------- 1 | name: Reusable Workflows 2 | on: 3 | workflow_call: # Reusable Workflowsを起動するイベント 4 | inputs: # Reusable Workflowsの入力パラメータ定義(平文) 5 | pr-number: 6 | type: string 7 | default: ${{ github.event.pull_request.number }} 8 | required: false 9 | description: プルリクエスト番号 10 | secrets: # Reusable Workflowsの入力パラメータ定義(Secrets) 11 | token: 12 | required: true 13 | description: GitHubトークン 14 | outputs: # Reusable Workflowsの出力値定義 15 | message: 16 | value: ${{ jobs.comment.outputs.pr-comment }} 17 | description: メッセージ 18 | jobs: # Reusable Workflowsのジョブ定義 19 | comment: 20 | runs-on: ubuntu-latest 21 | permissions: 22 | contents: read 23 | pull-requests: write 24 | steps: 25 | - uses: actions/checkout@v4 26 | - id: pr-comment 27 | run: | 28 | body="Welcome, ${GITHUB_ACTOR}" 29 | gh pr comment "${PR_NUMBER}" --body "${body}" 30 | echo "body=${body}" >>"${GITHUB_OUTPUT}" 31 | env: 32 | PR_NUMBER: ${{ inputs.pr-number }} 33 | GITHUB_TOKEN: ${{ secrets.token }} 34 | outputs: 35 | pr-comment: ${{ steps.pr-comment.outputs.body }} 36 | -------------------------------------------------------------------------------- /.github/workflows/run-name.yml: -------------------------------------------------------------------------------- 1 | name: Run name 2 | run-name: Run by @${{ github.actor }} # ワークフロー実行名の指定 3 | on: push 4 | jobs: 5 | print: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - run: echo "Hello" 9 | -------------------------------------------------------------------------------- /.github/workflows/schedule.yml: -------------------------------------------------------------------------------- 1 | name: Schedule 2 | on: 3 | schedule: # 定期実行イベント 4 | - cron: '*/15 * * * *' # 15分ごとに起動するcron式 5 | jobs: 6 | run: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - run: date 10 | -------------------------------------------------------------------------------- /.github/workflows/secret-scan.yml: -------------------------------------------------------------------------------- 1 | name: Secret scan 2 | on: pull_request 3 | jobs: 4 | scan: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - run: | # Secretlintの実行 9 | docker run --rm -v "$(pwd):$(pwd)" -w "$(pwd)" \ 10 | secretlint/secretlint secretlint --maskSecrets '**/*' 11 | -------------------------------------------------------------------------------- /.github/workflows/secrets.yml: -------------------------------------------------------------------------------- 1 | name: Secrets 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | env: 7 | PASSWORD: ${{ secrets.PASSWORD }} # Secretsの参照 8 | steps: 9 | - run: echo "${PASSWORD}" # ログ出力はマスクされる 10 | - run: echo "${PASSWORD:0:1} ${PASSWORD#?}" # ログ出力はマスクされない 11 | -------------------------------------------------------------------------------- /.github/workflows/sequential-jobs.yml: -------------------------------------------------------------------------------- 1 | name: Sequential jobs 2 | on: push 3 | jobs: 4 | first: # 依存ジョブがないので最初に実行される 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: sleep 10 && echo "First job" 8 | second: # firstジョブのあとに実行される 9 | runs-on: ubuntu-latest 10 | needs: [first] # needsキーへ依存するfirstジョブのIDを指定 11 | steps: 12 | - run: sleep 10 && echo "Second job" 13 | third: # secondジョブのあとに実行される 14 | runs-on: ubuntu-latest 15 | needs: [second] # needsキーへ依存するsecondジョブのIDを指定 16 | steps: 17 | - run: sleep 10 && echo "Third job" 18 | -------------------------------------------------------------------------------- /.github/workflows/share-job-data.yml: -------------------------------------------------------------------------------- 1 | name: Share job data 2 | on: push 3 | jobs: 4 | before: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - id: generate # ステップのID 8 | run: echo "result=Hello" >> "${GITHUB_OUTPUT}" # ステップレベルの出力値 9 | outputs: 10 | result: ${{ steps.generate.outputs.result }} # ジョブレベルの出力値 11 | after: 12 | runs-on: ubuntu-latest 13 | needs: [before] # 依存するジョブIDの指定 14 | steps: 15 | - env: 16 | RESULT: ${{ needs.before.outputs.result }} # 依存ジョブの出力値を参照 17 | run: echo "${RESULT}" 18 | -------------------------------------------------------------------------------- /.github/workflows/static-analysis.yml: -------------------------------------------------------------------------------- 1 | name: Static analysis 2 | on: 3 | pull_request: 4 | paths: ['.github/workflows/*.yml', '.github/workflows/*.yaml'] 5 | defaults: # デフォルトシェル 6 | run: 7 | shell: bash 8 | concurrency: # 自動キャンセル 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 5 # タイムアウト 15 | steps: 16 | - uses: actions/checkout@v4 17 | - run: | # 静的解析の実行 18 | docker run --rm -v "$(pwd):$(pwd)" -w "$(pwd)" rhysd/actionlint:latest 19 | -------------------------------------------------------------------------------- /.github/workflows/static-application-security-testing.yml: -------------------------------------------------------------------------------- 1 | name: Static Application Security Testing 2 | on: pull_request 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: actions/setup-python@v5 9 | with: 10 | python-version: 3.x 11 | - run: pip install bandit # Banditのインストール 12 | - run: bandit -r . # BanditでPythonのコードをスキャン 13 | -------------------------------------------------------------------------------- /.github/workflows/status-check-functions.yml: -------------------------------------------------------------------------------- 1 | name: Status check functions 2 | on: push 3 | jobs: 4 | fail: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - run: exit 1 # 終了ステータスがゼロ以外なので、エラーが発生する 8 | - run: echo "Hello" 9 | if: ${{ failure() }} # エラーが発生しても、failure関数があるので実行される 10 | -------------------------------------------------------------------------------- /.github/workflows/test-action.yml: -------------------------------------------------------------------------------- 1 | name: Test action 2 | on: pull_request 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | env: 7 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 8 | permissions: 9 | contents: write 10 | pull-requests: write 11 | steps: 12 | - uses: actions/checkout@v4 13 | - name: Setup # テストの準備 14 | run: date > foo.md 15 | - name: Exercise # テスト対象コードの実行 16 | id: exercise 17 | uses: ./ 18 | with: 19 | message: Test 20 | - name: Verify # 実行結果の検証 21 | run: | 22 | set -x 23 | test "$(gh pr view "${BRANCH}" --json title --jq .title)" = "Test" 24 | env: 25 | BRANCH: ${{ steps.exercise.outputs.branch }} 26 | - name: Teardown # テストの後始末 27 | if: ${{ always() }} 28 | run: | 29 | gh pr close "${BRANCH}" || true 30 | git push origin "${BRANCH}" --delete || true 31 | env: 32 | BRANCH: ${{ steps.exercise.outputs.branch }} 33 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: # プルリクエストが作成されたら起動 4 | paths: ['go/**/*.go'] # ただしGoのファイル変更時のみ 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 # ステップ1: チェックアウト 10 | - uses: actions/setup-go@v5 # ステップ2: 言語セットアップ 11 | with: 12 | go-version: '1.22' 13 | - run: go test go/excellent/*.go # ステップ3: テストの実行 14 | -------------------------------------------------------------------------------- /.github/workflows/timeout.yml: -------------------------------------------------------------------------------- 1 | name: Timeout 2 | on: push 3 | jobs: 4 | sleep: 5 | runs-on: ubuntu-latest 6 | timeout-minutes: 1 # ワークフローのタイムアウトを1分に設定 7 | steps: 8 | - run: sleep 120 # 2分(120秒)スリープさせる 9 | -------------------------------------------------------------------------------- /.github/workflows/variables.yml: -------------------------------------------------------------------------------- 1 | name: Variables 2 | on: push 3 | jobs: 4 | print: 5 | runs-on: ubuntu-latest 6 | env: 7 | USERNAME: ${{ vars.USERNAME }} # Variablesの参照 8 | steps: 9 | - run: echo "${USERNAME}" 10 | -------------------------------------------------------------------------------- /.github/workflows/workflow-error.yml: -------------------------------------------------------------------------------- 1 | name: Workflow error 2 | on: push 3 | jobs: 4 | run: 5 | run-on: ubuntu-latest 6 | steps: 7 | - run: date 8 | -------------------------------------------------------------------------------- /.github/workflows/yaml-error.yml: -------------------------------------------------------------------------------- 1 | name: YAML error 2 | on: push 3 | jobs: 4 | run: 5 | runs-on: ubuntu-latest 6 | steps: # インデントが2文字ズレている! 7 | - run: echo "YAML Syntax Error" 8 | -------------------------------------------------------------------------------- /.go-version: -------------------------------------------------------------------------------- 1 | 1.22 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # リポジトリ全体のコードオーナーを設定する(マッチする設定がない場合のフォールバック先) 2 | * @octocat 3 | 4 | # 特定のファイル種別のみコードオーナーをTeamに設定する 5 | *.txt @example-org/octocat-team 6 | 7 | # 特定ディレクトリ配下のコードオーナーを、複数アカウントへ設定する 8 | .github/workflow/ @github @example-org/octocat-team 9 | -------------------------------------------------------------------------------- /CODEOWNERS.simple: -------------------------------------------------------------------------------- 1 | * @octocat 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 『GitHub CI/CD実践ガイド』サンプルコード 2 | 3 | このリポジトリでは『**[GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用](https://gihyo.jp/book/2024/978-4-297-14173-8)**』のサンプルコードを公開しています。 4 | 5 | 6 | ## コピー用コマンド 7 | 8 | - [第11章](/command/11/README.md) 9 | - [第12章](/command/12/README.md) 10 | 11 | ## 第2章 12 | 13 | - [コード2.1](/.github/workflows/hello.yml) 14 | - [コード2.2](/.github/workflows/workflow-error.yml) 15 | - [コード2.3](/.github/workflows/yaml-error.yml) 16 | - [コード2.4](/.github/workflows/manual.yml) 17 | - [コード2.5](/.github/workflows/schedule.yml) 18 | 19 | ## 第3章 20 | 21 | - [コード3.1](/.github/workflows/contexts.yml) 22 | - [コード3.2](/.github/workflows/environment-variables.yml) 23 | - [コード3.3](/.github/workflows/override-environment-variables.yml) 24 | - [コード3.4](/.github/workflows/intermediate-environment-variables.yml) 25 | - [コード3.5](/.github/workflows/variables.yml) 26 | - [コード3.6](/.github/workflows/secrets.yml) 27 | - [コード3.7](/.github/workflows/literals.yml) 28 | - [コード3.8](/.github/workflows/compare-functions.yml) 29 | - [コード3.9](/.github/workflows/generate-functions.yml) 30 | - [コード3.10](/.github/workflows/json-functions.yml) 31 | - [コード3.11](/.github/workflows/hash-functions.yml) 32 | - [コード3.12](/.github/workflows/conditions.yml) 33 | - [コード3.13](/.github/workflows/status-check-functions.yml) 34 | - [コード3.14](/.github/workflows/conditions-workflow.yml) 35 | - [コード3.15](/.github/workflows/naming.yml) 36 | - [コード3.16](/.github/workflows/run-name.yml) 37 | - [コード3.17](/.github/workflows/missing-share-data.yml) 38 | - [コード3.18](/.github/workflows/github-output.yml) 39 | - [コード3.19](/.github/workflows/github-env.yml) 40 | - [コード3.20](/.github/workflows/comment.yml) 41 | 42 | ## 第4章 43 | 44 | - [コード4.1](/go/excellent/main.go) 45 | - [コード4.2](/go/excellent/main_test.go) 46 | - [コード4.3](/.github/workflows/test.yml) 47 | - [コード4.4](/.go-version) 48 | - [コード4.5](/.github/workflows/invalid.yml) 49 | - [コード4.6](/.github/workflows/static-analysis.yml) 50 | - [コード4.7](/.github/workflows/timeout.yml) 51 | - [コード4.8](/.github/workflows/change-shell.yml) 52 | - [コード4.9](/.github/workflows/concurrency.yml) 53 | - [コード4.10](/.github/workflows/auto-cancel.yml) 54 | 55 | ## 第5章 56 | 57 | - [コード5.1](/.github/workflows/debug-log.yml) 58 | - [コード5.2](/.github/workflows/bash-tracing.yml) 59 | - [コード5.3](/.github/workflows/log-group.yml) 60 | - [コード5.4](/.github/workflows/add-mask.yml) 61 | - [コード5.5](/.github/workflows/annotation.yml) 62 | - [コード5.6](/.github/workflows/job-summaries.yml) 63 | - [コード5.7](/.github/workflows/parallel-jobs.yml) 64 | - [コード5.8](/.github/workflows/sequential-jobs.yml) 65 | - [コード5.9](/.github/workflows/share-job-data.yml) 66 | - [コード5.10](/.github/workflows/matrix.yml) 67 | - [コード5.11](/.github/workflows/multi-dimension-matrix.yml) 68 | - [コード5.12](/.github/workflows/manual-matrix.yml) 69 | - [コード5.13](/.github/workflows/environments.yml) 70 | - [コード5.14](/.github/workflows/cache.yml) 71 | - [コード5.15](/.github/workflows/artifacts.yml) 72 | 73 | ## 第6章 74 | 75 | - [コード6.1](/.github/actions/dump/action.yml) 76 | - [コード6.2](/.github/workflows/dump.yml) 77 | 78 | ## 第7章 79 | 80 | - [コード7.1](/CODEOWNERS.simple) 81 | - [コード7.2](/CODEOWNERS) 82 | 83 | ## 第8章 84 | 85 | - [コード8.1](/.github/workflows/old.yml) 86 | - [コード8.2](/.github/dependabot.yml) 87 | - [コード8.3](/.github/dependabot-ignore.yml) 88 | - [コード8.4](/.github/workflows/auto-merge.yml) 89 | - [コード8.5](/.github/workflows/auto-patch-merge.yml) 90 | 91 | ## 第9章 92 | 93 | - [コード9.1](/.github/release.yml) 94 | - [コード9.2](/.github/release-exclude.yml) 95 | - [コード9.3](/go/example/main.go) 96 | - [コード9.4](/.github/workflows/release.yml) 97 | 98 | ## 第10章 99 | 100 | - [コード10.1](/docker/example/Dockerfile) 101 | - [コード10.2](/.github/workflows/publish.yml) 102 | 103 | ## 第11章 104 | 105 | - [コード11.2](/.github/workflows/openid-connect.yml) 106 | 107 | ## 第12章 108 | 109 | - [コード12.1](/.github/actions/container-build/action.yml) 110 | - [コード12.3](/.github/actions/container-deploy/action.yml) 111 | - [コード12.4](/.github/workflows/deploy.yml) 112 | - [コード12.5](/docker/ecs/Dockerfile) 113 | 114 | ## 第13章 115 | 116 | - [コード13.1](/action.yml) 117 | - [コード13.2](/.github/workflows/test-action.yml) 118 | - [コード13.3](/.github/scripts/bump.sh) 119 | - [コード13.4](/.github/workflows/release-action.yml) 120 | 121 | ## 第14章 122 | 123 | - [コード14.1](/.github/workflows/reusable-workflows.yml) 124 | - [コード14.2](/.github/workflows/call.yml) 125 | - [コード14.3](/.github/workflows/dynamic-matrix.yml) 126 | - [コード14.4](/.github/workflows/convert.yml) 127 | - [コード14.5](/.github/workflows/continue-on-error.yml) 128 | - [コード14.6](/.github/workflows/fail-fast-matrix.yml) 129 | - [コード14.9](/.github/workflows/flow-control.yml) 130 | 131 | ## 第16章 132 | 133 | - [コード16.1](/.github/workflows/secret-scan.yml) 134 | - [コード16.2](/.github/workflows/static-application-security-testing.yml) 135 | - [コード16.3](/.github/workflows/container-image-scan.yml) 136 | - [コード16.4](/.github/workflows/prevent-security-misconfigurations.yml) 137 | - [コード16.5](/policy/workflow.rego) 138 | - [コード16.6](/.github/workflows/conftest.yml) 139 | 140 | ## 第17章 141 | 142 | - [コード17.1](/.github/workflows/cross-repo.yml) 143 | - [コード17.2](/.github/scripts/token.sh) 144 | - [コード17.3](/.github/workflows/modified-cross-repo.yml) 145 | 146 | ## License 147 | 148 | Apache 2 Licensed. See LICENSE for full details. 149 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: Create PR 2 | description: | 3 | 変更したファイルをコミットし、プルリクエストを作成します。 4 | プルリクエストのタイトルや本文には、コミットメッセージがそのまま利用されます。 5 | パーミッションに「contents: write」と「pull-requests: write」が必要です。 6 | inputs: 7 | message: # アクションの入力 8 | required: true 9 | description: コミットメッセージ 10 | outputs: 11 | branch: # アクションの出力 12 | value: ${{ steps.pr.outputs.branch }} 13 | description: プルリクエストのブランチ 14 | runs: 15 | using: composite 16 | steps: 17 | - id: pr 18 | shell: bash 19 | env: 20 | USERNAME: github-actions[bot] 21 | EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 22 | MESSAGE: ${{ inputs.message }} 23 | BRANCH: auto/${{ github.run_id }}/${{ github.run_attempt }} 24 | GITHUB_TOKEN: ${{ github.token }} 25 | run: | 26 | echo "branch=${BRANCH}" >> "${GITHUB_OUTPUT}" 27 | git config --global user.name "${USERNAME}" # Gitのユーザー設定 28 | git config --global user.email "${EMAIL}" 29 | git switch -c "${BRANCH}" # コミットとプッシュ 30 | git add . 31 | git commit -m "${MESSAGE}" 32 | git push origin "${BRANCH}" # プルリクエストの作成(↓) 33 | gh pr create --head "${BRANCH}" --title "${MESSAGE}" --body "${MESSAGE}" 34 | branding: # ブランディング設定 35 | color: green # 緑色 36 | icon: shield # シールドアイコン 37 | -------------------------------------------------------------------------------- /command/11/README.md: -------------------------------------------------------------------------------- 1 | # 第11章 2 | 3 | ## プライベートリポジトリの作成 4 | 5 | ```shell 6 | gh repo create gh-oidc --private --clone --add-readme 7 | cd gh-oidc 8 | ``` 9 | 10 | 11 | ## AWSにおけるOpenID Connectの利用準備 12 | 13 | ココから先はAWS CloudShellでの作業です。 14 | 15 | ### AWS CLIのバージョン確認 16 | 17 | ```shell 18 | aws --version 19 | ``` 20 | 21 | ### AWSアカウントIDの取得 22 | 23 | ```shell 24 | aws sts get-caller-identity --query Account --output text 25 | ``` 26 | 27 | ## OpenID Connect Provider 28 | 29 | ```shell 30 | aws iam create-open-id-connect-provider \ 31 | --url https://token.actions.githubusercontent.com \ 32 | --client-id-list sts.amazonaws.com \ 33 | --thumbprint-list 1234567890123456789012345678901234567890 34 | ``` 35 | 36 | 37 | ## IAMロール 38 | 39 | ### 利用するリポジトリ 40 | 41 | 「`OWNER`」と「`REPO`」はご自身の環境にあわせて変更してください。 42 | 43 | ```shell 44 | export GITHUB_REPOSITORY=/ 45 | ``` 46 | 47 | ### Identity ProviderのURL 48 | 49 | ```shell 50 | export PROVIDER_URL=token.actions.githubusercontent.com 51 | ``` 52 | 53 | ### AWSアカウントID 54 | 55 | ```shell 56 | export AWS_ID=$(aws sts get-caller-identity --query Account --output text) 57 | ``` 58 | 59 | ### IAMロール名 60 | 61 | ```shell 62 | export ROLE_NAME=github-actions 63 | ``` 64 | 65 | 66 | #### Assume Roleポリシーを定義したJSONファイルの作成 67 | 68 | ```shell 69 | cat < assume_role_policy.json 70 | { 71 | "Version": "2012-10-17", 72 | "Statement": [ 73 | { 74 | "Effect": "Allow", 75 | "Action": "sts:AssumeRoleWithWebIdentity", 76 | "Principal": { 77 | "Federated": "arn:aws:iam::${AWS_ID}:oidc-provider/${PROVIDER_URL}" 78 | }, 79 | "Condition": { 80 | "StringLike": { 81 | "${PROVIDER_URL}:sub": "repo:${GITHUB_REPOSITORY}:*" 82 | } 83 | } 84 | } 85 | ] 86 | } 87 | EOF 88 | ``` 89 | 90 | #### IAMロールの作成 91 | 92 | ```shell 93 | aws iam create-role \ 94 | --role-name $ROLE_NAME \ 95 | --assume-role-policy-document file://assume_role_policy.json 96 | ``` 97 | 98 | #### IAMポリシーのアタッチ 99 | 100 | ```shell 101 | aws iam attach-role-policy \ 102 | --role-name $ROLE_NAME \ 103 | --policy-arn arn:aws:iam::aws:policy/IAMReadOnlyAccess 104 | ``` 105 | 106 | 107 | ## OpenID ConnectによるAWS連携 108 | 109 | ココから先はローカル環境での作業です。 110 | 111 | ### AWSアカウントIDのSecrets登録 112 | 113 | ```shell 114 | gh secret set AWS_ID --body "" 115 | ``` 116 | 117 | 118 | ### IAMロール名のSecrets登録 119 | 120 | ```shell 121 | gh secret set ROLE_NAME --body "" 122 | ``` 123 | -------------------------------------------------------------------------------- /command/12/README.md: -------------------------------------------------------------------------------- 1 | # 第12章 2 | 3 | ## AWS Copilotによるプロビジョニング 4 | 5 | ココから先はAWS CloudShellでの作業です。 6 | 7 | ### AWS Copilotのバージョン確認 8 | 9 | ```shell 10 | copilot --version 11 | ``` 12 | 13 | ### AWS Copilotで使用する値を環境変数へセット 14 | 15 | ```shell 16 | export APP_NAME=demo 17 | export SVC_NAME=example 18 | export ENV_NAME=test 19 | ``` 20 | 21 | 22 | ### マニフェストファイルの作成 23 | 24 | ```shell 25 | copilot app init $APP_NAME 26 | copilot svc init --name $SVC_NAME --app $APP_NAME \ 27 | --image nginx --port 80 --svc-type "Load Balanced Web Service" 28 | ``` 29 | 30 | 31 | ## テスト環境の構築 32 | 33 | ### リソースの作成 34 | 35 | ```shell 36 | copilot env init --name $ENV_NAME --app $APP_NAME \ 37 | --profile default --default-config 38 | copilot env deploy --name $ENV_NAME 39 | copilot svc deploy --name $SVC_NAME --env $ENV_NAME 40 | ``` 41 | 42 | ### curlによる動作確認 43 | 44 | URLはご自身のものと差し替えてください。 45 | 46 | ```shell 47 | curl -I http://demo-xxx.ap-northeast-1.elb.amazonaws.com 48 | ``` 49 | 50 | 51 | ## デプロイメントIAMロール 52 | 53 | ### ポリシードキュメントの作成 54 | 55 | ```shell 56 | cat < policy.json 57 | { 58 | "Version": "2012-10-17", 59 | "Statement": [ 60 | { 61 | "Effect": "Allow", 62 | "Action": [ 63 | "ecr:GetAuthorizationToken", 64 | "ecr:BatchGetImage", 65 | "ecr:BatchCheckLayerAvailability", 66 | "ecr:CompleteLayerUpload", 67 | "ecr:GetDownloadUrlForLayer", 68 | "ecr:InitiateLayerUpload", 69 | "ecr:PutImage", 70 | "ecr:UploadLayerPart", 71 | "ecs:DescribeTaskDefinition", 72 | "ecs:RegisterTaskDefinition", 73 | "ecs:UpdateService", 74 | "ecs:DescribeServices" 75 | ], 76 | "Resource": "*" 77 | }, 78 | { 79 | "Effect": "Allow", 80 | "Action": ["iam:PassRole"], 81 | "Resource": "*", 82 | "Condition": { 83 | "StringLike": { 84 | "iam:PassedToService": "ecs-tasks.amazonaws.com" 85 | } 86 | } 87 | } 88 | ] 89 | } 90 | EOF 91 | ``` 92 | 93 | ### IAMポリシーの新規作成 94 | 95 | ```shell 96 | export POLICY_NAME=deploy-${APP_NAME}-${SVC_NAME} 97 | aws iam create-policy --policy-name $POLICY_NAME \ 98 | --policy-document file://policy.json 99 | ``` 100 | 101 | ### IAMロールへ作成したIAMポリシーをアタッチ 102 | 103 | ```shell 104 | export ROLE_NAME=github-actions 105 | export AWS_ID=$(aws sts get-caller-identity --query Account --output text) 106 | aws iam attach-role-policy --role-name $ROLE_NAME \ 107 | --policy-arn "arn:aws:iam::${AWS_ID}:policy/${POLICY_NAME}" 108 | ``` 109 | 110 | 111 | ## デプロイ情報の取得 112 | 113 | ### ECSクラスター名の取得 114 | 115 | ```shell 116 | aws ecs list-clusters --output text \ 117 | --query "clusterArns[?contains(@, '${APP_NAME}-${ENV_NAME}')]" \ 118 | | cut -d/ -f2 119 | ``` 120 | 121 | ### ECSサービス名の取得 122 | 123 | `--cluster`フラグの値は、手前で取得したECSクラスター名に差し替えてください。 124 | 125 | ```shell 126 | aws ecs list-services --cluster "" --output text \ 127 | --query "serviceArns[?contains(@, '${APP_NAME}-${ENV_NAME}')]" \ 128 | | cut -d/ -f3 129 | ``` 130 | 131 | ### タスク定義名の取得 132 | 133 | ```shell 134 | aws ecs list-task-definitions --status ACTIVE --sort DESC --output text \ 135 | --query "taskDefinitionArns[?contains(@, '${APP_NAME}-${ENV_NAME}')]" \ 136 | | cut -d/ -f2 | cut -d: -f1 137 | ``` 138 | 139 | ### ECRリポジトリURIの取得 140 | 141 | ```shell 142 | aws ecr describe-repositories --output text \ 143 | --query "repositories[?contains(repositoryUri, '$APP_NAME')].repositoryUri" 144 | ``` 145 | 146 | ### コンテナ名の取得 147 | 148 | ```shell 149 | echo $SVC_NAME 150 | ``` 151 | 152 | 153 | ## デプロイ情報の登録 154 | 155 | ココから先はローカル環境での作業です。 156 | 157 | ```shell 158 | gh variable set ECS_CLUSTER_NAME --body "" 159 | gh variable set ECS_SERVICE_NAME --body "" 160 | gh variable set TASK_DEFINITION_NAME --body "<タスク定義名>" 161 | gh variable set ECR_REPOSITORY_URI --body "" 162 | gh variable set CONTAINER_NAME --body "<コンテナ名>" 163 | ``` 164 | 165 | 166 | ## デプロイの実行 167 | 168 | ### デプロイワークフローの実行 169 | 170 | ```shell 171 | gh workflow run deploy.yml 172 | ``` 173 | 174 | ### デプロイの実行結果を確認 175 | 176 | URLはご自身のものと差し替えてください。 177 | 178 | ```shell 179 | curl http://demo-xxxx.ap-northeast-1.elb.amazonaws.com 180 | ``` 181 | 182 | 183 | ## 本番環境の構築 184 | 185 | ココから先はAWS CloudShellでの作業です。 186 | 187 | ```shell 188 | export ENV_NAME=prod 189 | ``` 190 | 191 | 192 | ## Environmentsによるデプロイ情報の管理 193 | 194 | ココから先はローカル環境での作業です。 195 | 196 | ```shell 197 | export ENV_NAME=prod 198 | gh variable set ECS_CLUSTER_NAME --body "" --env $ENV_NAME 199 | gh variable set ECS_SERVICE_NAME --body "" --env $ENV_NAME 200 | gh variable set TASK_DEFINITION_NAME --body "<タスク定義名>" --env $ENV_NAME 201 | ``` 202 | 203 | ## 複数環境向けデプロイワークフロー 204 | 205 | ### テスト環境 206 | 207 | ```shell 208 | gh workflow run deploy.yml -f environment-name=test 209 | ``` 210 | 211 | ### 本番環境 212 | 213 | ```shell 214 | gh workflow run deploy.yml -f environment-name=prod 215 | ``` 216 | 217 | 218 | ## 実行環境の後始末 219 | 220 | ココから先はAWS CloudShellでの作業です。 221 | 222 | ### AWS Copilotで作成したリソースの削除 223 | 224 | ```shell 225 | copilot app delete --yes 226 | ``` 227 | 228 | ### OpenID Connect Providerの削除 229 | 230 | ```shell 231 | aws iam delete-open-id-connect-provider --open-id-connect-provider-arn \ 232 | arn:aws:iam::${AWS_ID}:oidc-provider/token.actions.githubusercontent.com 233 | ``` 234 | -------------------------------------------------------------------------------- /docker/ecs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.25-alpine 2 | RUN echo 'Hello Amazon ECS' > /usr/share/nginx/html/index.html 3 | -------------------------------------------------------------------------------- /docker/example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.25-alpine 2 | RUN echo 'Hello GitHub Packages' > /usr/share/nginx/html/index.html 3 | -------------------------------------------------------------------------------- /go/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var version string // ビルド時にldflagsフラグ経由でバージョンを埋め込むための変数 6 | 7 | func main() { 8 | fmt.Printf("Example %s\n", version) 9 | } 10 | -------------------------------------------------------------------------------- /go/excellent/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func EvenOrOdd(number int) string { 4 | if number%2 == 0 { 5 | return "even" 6 | } else { 7 | return "odd" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /go/excellent/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestEvenOrOdd(t *testing.T) { 6 | result := EvenOrOdd(10) 7 | if result != "even" { 8 | t.Errorf("expected: even, actual: %s", result) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /policy/workflow.rego: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | deny[msg] { # ワークフローレベルのpermissionsが省略されていたら拒否 4 | not input.permissions 5 | msg = "Workflow permissions are missing" 6 | } 7 | 8 | deny[msg] { # ワークフローレベルのpermissionsで空以外が指定されていたら拒否 9 | input.permissions != {} 10 | msg = sprintf("Workflow permissions are not empty: %v", [input.permissions]) 11 | } 12 | --------------------------------------------------------------------------------