脱get-diff-actionとecspresso diffをGitHub Actionsで実行する話¶
脱get-diff-actionとecspresso diffをGitHub Actionsで実行する話 - TORANA TECH BLOG 2024-03-29 SREのクラシマです。 弊社ではGitHub - technote-space/get-diff-action: GitHub Actions to get git diffを多用していたのですが、2023年11月にarchivedになってしまいました。 同actionではnode16を利用していることもあり、git diffコマンドに書き換えることにしました。 ついでなので、terraformと一緒に利用しているecspressoについて、tfcmtのようにecspresso diffがPull Request上で見られると便利だね、ということで同僚が作ったecspresso diff actionについても紹介します。
ecspresso diff action全容
---
name: Diff task definition
on:
pull_request:
paths:
- 'ecspresso/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
HEAD_REF: ${{ github.head_ref }}
START_COMMENT: "### ecspresso diff"
jobs:
get-target-dirs:
name: get target dirs
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
target-dirs: ${{ steps.target-dirs.outputs.dirs }}
steps:
- name: Checkout
timeout-minutes: 3
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
sparse-checkout: |
ecspresso
- name: Get target dirs
timeout-minutes: 2
id: target-dirs
run: |
set -xv
diff_dirs=$(git diff --diff-filter=AMRCD \
--name-only \
"origin/$GITHUB_BASE_REF..${GITHUB_REF/refs\//}" \
-- ecspresso \
| xargs dirname \
| sort -u \
| jq -cnR '[inputs | select(length > 0)]'
)
echo "#diff : ${diff_dirs}"
echo "dirs=${diff_dirs}" >> "$GITHUB_OUTPUT"
- name: Comment remove PR
timeout-minutes: 1
env:
GH_TOKEN: ${{ secrets.PAT }}
run: |
set -xv
remove_comment_ids=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
--jq '.[] | select(.user.login == "torana-dev-user") | select(.body | startswith("${{ env.START_COMMENT }}\n")) | .id')
if [ -n "$remove_comment_ids" ]; then
for comment_id in $remove_comment_ids; do
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"repos/${{ github.repository }}/issues/comments/$comment_id"
done
fi
diff:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
needs: [get-target-dirs]
timeout-minutes: 10
strategy:
matrix:
target-dir: ${{ fromJson(needs.get-target-dirs.outputs.target-dirs) }}
steps:
- name: Checkout
if: needs.get-target-dirs.outputs.target-dirs != '[]' && needs.get-target-dirs.outputs.target-dirs != ''
timeout-minutes: 3
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
sparse-checkout: |
ecspresso
- uses: aquaproj/aqua-installer@fd2089d1f56724d6456f24d58605e6964deae124 # v2.3.2
with:
aqua_version: v2.25.1
- name: Configure AWS credentials
timeout-minutes: 1
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-oidc-role
aws-region: ap-northeast-1
- name: Get service name
id: get-service-name
run: |
service_name=$(echo "${{ matrix.target-dir }}" | awk -F'/' '{print $3"-"$2}')
echo "service_name=$service_name" >> "$GITHUB_OUTPUT"
- name: ecspresso diff
id: ecspresso-diff
timeout-minutes: 2
working-directory: ${{ matrix.target-dir }}
run: |
set -xv
# イメージタグは既存の値を使う(差分を無視するため)
actual_image_tag=$(aws ecs describe-task-definition \
--task-definition "${{ steps.get-service-name.outputs.service_name }}" \
| jq -r '.taskDefinition.containerDefinitions[0].image | match(":(.*)$").captures[0].string')
diff=$(IMAGE_TAG="$actual_image_tag" ecspresso diff --config ecspresso.yml)
{
echo "diff<<EOF"
echo "$diff"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Comment on PR
timeout-minutes: 1
env:
GH_TOKEN: ${{ secrets.PAT }}
run: |
set -xv
comment="${{ env.START_COMMENT }}
#### Target - ${{ matrix.target-dir }}
"
# shellcheck disable=SC2078
if [ ${{ contains(steps.ecspresso-diff.outputs.diff, '+') }} ] || [ ${{ contains(steps.ecspresso-diff.outputs.diff, '-') }} ]; then
diff='${{ format(
'<details><summary>Show Diff</summary>
```diff
{0}
```
</details>',
steps.ecspresso-diff.outputs.diff
) }}'
else
diff='```
No changes
```'
fi
gh pr comment "${{ env.HEAD_REF }}" --body "$comment""$diff"
steps:
- name: Checkout
timeout-minutes: 3
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
sparse-checkout: |
ecspresso
- uses: technote-space/get-diff-action@f27caffdd0fb9b13f4fc191c016bb4e0632844af # v6
- name: Get target dirs
timeout-minutes: 2
id: target-dirs
run: |
diff_dirs=$(echo ${{ env.GIT_DIFF }} \
| tr ' ' '\n' \
| grep "ecspresso/" \
| xargs -I{} dirname {} \
| sort -u \
| tr "\n" " " \
| jq -cR 'split("\n") | map(select(length > 0))'
)
echo "#diff : ${diff_dirs}"
- name: target branch
id: target_branch
run: |
set -xv
branch=""
from=""
to=""
if [ "$GITHUB_EVENT_NAME" = "push" ]; then
branch="$GITHUB_REF_NAME"
from="${{ toJSON(github.event.before) }}"
to="${{ toJSON(github.event.after) }}"
else
branch="$GITHUB_BASE_REF"
from="origin/$GITHUB_BASE_REF"
to="${GITHUB_REF/refs\//}"
fi
{
echo "branch=$branch"
echo "from=$from"
echo "to=$to"
} >> "$GITHUB_OUTPUT"
- name: get diff
run: |
set -xv
diff=$(git diff --diff-filter="AMRCD" \
--name-only \
"${{ steps.target_branch.outputs.from }}...${{ steps.target_branch.outputs.to }}" \
-- "**.tf" \
| xargs)
echo "GIT_DIFF=$diff" >> "$GITHUB_ENV"