Skip to content

Commit 9dbd8dc

Browse files
committed
Add a workflow to deal with provider locks
- if dependabot opened the PR, commit any updated lock files - if a human opened the PR, fail if lock files are not updated
1 parent e92d791 commit 9dbd8dc

2 files changed

Lines changed: 209 additions & 9 deletions

File tree

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
name: Update Provider Lock Files
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "infra/shared/versions.tf"
7+
8+
jobs:
9+
update-locks:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
18+
with:
19+
# Use the pull request head ref to ensure we're on the PR branch
20+
ref: ${{ github.head_ref }}
21+
# Use PAT for Dependabot PRs, regular token for others
22+
# The current PAT is whi-tw's, it needs repo:write permissions
23+
# We need to update it if they move on from the team, or if it expires.
24+
token: ${{ github.actor == 'dependabot[bot]' && secrets.DEPENDABOT_PAT || secrets.GITHUB_TOKEN }}
25+
26+
- name: Set up Go
27+
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
28+
29+
- name: Install tfupdate
30+
run: |
31+
go install github.com/minamijoyo/tfupdate@latest
32+
33+
- name: Run lock update script
34+
run: |
35+
./infra/scripts/upgrade_tf_version.sh --lock-only
36+
37+
- name: Check for changed files
38+
id: git-check
39+
run: |
40+
# Check if there are any changes
41+
if git diff --quiet && git diff --cached --quiet; then
42+
echo "changed=false" >> "${GITHUB_OUTPUT}"
43+
echo "No changes detected"
44+
else
45+
echo "changed=true" >> "${GITHUB_OUTPUT}"
46+
echo "Changes detected:"
47+
git diff --name-only
48+
fi
49+
50+
- name: Handle Dependabot PR - commit lock files
51+
if: steps.git-check.outputs.changed == 'true' && github.actor == 'dependabot[bot]'
52+
env:
53+
PUSH_REF: ${{ github.head_ref }}
54+
run: |
55+
git config --local user.email "action@github.com"
56+
git config --local user.name "GitHub Action"
57+
58+
# Add only .terraform.lock.hcl files
59+
git add '**/.terraform.lock.hcl'
60+
61+
# Check if there are staged changes
62+
if git diff --cached --quiet; then
63+
echo "No .terraform.lock.hcl files to commit"
64+
else
65+
git commit -m "Update provider lock files"
66+
# Push using the PAT token configured in checkout
67+
git push origin HEAD:"${PUSH_REF}"
68+
fi
69+
70+
- name: Check for uncommitted changes (Dependabot PR)
71+
if: github.actor == 'dependabot[bot]'
72+
run: |
73+
# After committing lock files, check if there are still any changes
74+
if ! git diff --quiet || ! git diff --cached --quiet; then
75+
echo "Error: There are still uncommitted changes after processing lock files:"
76+
git status --porcelain
77+
echo ""
78+
echo "Changed files:"
79+
git diff --name-only
80+
if git diff --cached --quiet; then
81+
echo "No staged changes"
82+
else
83+
echo "Staged changes:"
84+
git diff --cached --name-only
85+
fi
86+
echo ""
87+
echo "This suggests there are changes beyond just .terraform.lock.hcl files that need attention."
88+
exit 1
89+
else
90+
echo "All changes have been properly handled"
91+
fi
92+
93+
- name: Check for missing lock updates (Non-Dependabot PR)
94+
if: steps.git-check.outputs.changed == 'true' && github.actor != 'dependabot[bot]'
95+
env:
96+
COMMENT_MARKER: "<!-- provider-locks: missing updates -->"
97+
GH_TOKEN: ${{ github.token }}
98+
run: |
99+
# shellcheck disable=SC2296
100+
# shellcheck disable=SC2016
101+
echo "Error: Provider lock files are out of date!"
102+
echo ""
103+
echo "You have modified infra/shared/versions.tf but the corresponding .terraform.lock.hcl files"
104+
echo "have not been updated. Please run the following command locally and commit the changes:"
105+
echo ""
106+
echo " ./infra/scripts/upgrade_tf_version.sh --lock-only"
107+
echo ""
108+
echo "Changed files detected:"
109+
git status --porcelain
110+
echo ""
111+
git diff --name-only
112+
113+
# Leave a comment on the PR
114+
cat <<EOF > "${{runner.temp}}/pr-comment.md"
115+
> [!CAUTION]
116+
> **Provider lock files are out of date!**
117+
>
118+
> You have modified \`infra/shared/versions.tf\` but the corresponding \`.terraform.lock.hcl\` files
119+
> have not been updated. Please run the following command locally and commit the changes:
120+
>
121+
> \`\`\`bash
122+
> ./infra/scripts/upgrade_tf_version.sh --lock-only
123+
> \`\`\`
124+
125+
${COMMENT_MARKER}
126+
EOF
127+
128+
# Remove any existing comments from this workflow
129+
old_comment_ids=$(gh api "repos/{owner}/{repo}/issues/${{github.event.pull_request.number}}/comments" --jq 'map(select((.user.login == "github-actions[bot]") and (.body | endswith($ENV.COMMENT_MARKER + "\n")))) | .[].id')
130+
for comment_id in $old_comment_ids; do
131+
gh api -X DELETE "repos/{owner}/{repo}/issues/comments/${comment_id}"
132+
done
133+
134+
gh pr comment "${{github.event.pull_request.html_url}}" --body-file "${{runner.temp}}/pr-comment.md"
135+
136+
exit 1
137+
138+
- name: Comment on Dependabot PR success
139+
if: steps.git-check.outputs.changed == 'true' && github.actor == 'dependabot[bot]'
140+
env:
141+
COMMENT_MARKER: "<!-- provider-locks: dependabot updated -->"
142+
GH_TOKEN: ${{ github.token }}
143+
run: |
144+
# shellcheck disable=SC2296
145+
# shellcheck disable=SC2016
146+
# Leave a comment on the PR
147+
cat <<EOF > "${{runner.temp}}/pr-comment.md"
148+
> [!NOTE]
149+
> **Provider lock files have been automatically updated**
150+
>
151+
> This Dependabot PR modified \`infra/shared/versions.tf\`, so the corresponding
152+
> \`.terraform.lock.hcl\` files have been automatically updated and committed.
153+
>
154+
> The changes are ready for review and merge.
155+
156+
${COMMENT_MARKER}
157+
EOF
158+
159+
# Remove any existing comments from this workflow
160+
old_comment_ids=$(gh api "repos/{owner}/{repo}/issues/${{github.event.pull_request.number}}/comments" --jq 'map(select((.user.login == "github-actions[bot]") and (.body | endswith($ENV.COMMENT_MARKER + "\n")))) | .[].id')
161+
for comment_id in $old_comment_ids; do
162+
gh api -X DELETE "repos/{owner}/{repo}/issues/comments/${comment_id}"
163+
done
164+
165+
gh pr comment "${{github.event.pull_request.html_url}}" --body-file "${{runner.temp}}/pr-comment.md"
166+
167+
- name: Remove stale comments when no changes needed
168+
if: steps.git-check.outputs.changed == 'false'
169+
env:
170+
COMMENT_MARKER_MISSING: "<!-- provider-locks: missing updates -->"
171+
COMMENT_MARKER_DEPENDABOT: "<!-- provider-locks: dependabot updated -->"
172+
GH_TOKEN: ${{ github.token }}
173+
run: |
174+
# shellcheck disable=SC2296
175+
# shellcheck disable=SC2016
176+
# Remove any existing comments from this workflow since no changes are needed
177+
old_comment_ids=$(gh api "repos/{owner}/{repo}/issues/${{github.event.pull_request.number}}/comments" --jq 'map(select((.user.login == "github-actions[bot]") and ((.body | endswith($ENV.COMMENT_MARKER_MISSING + "\n")) or (.body | endswith($ENV.COMMENT_MARKER_DEPENDABOT + "\n"))))) | .[].id')
178+
for comment_id in $old_comment_ids; do
179+
echo "Removing stale comment: $comment_id"
180+
gh api -X DELETE "repos/{owner}/{repo}/issues/comments/${comment_id}"
181+
done
182+
183+
echo "No provider lock updates needed - removed any stale comments"

infra/scripts/upgrade_tf_version.sh

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ IGNORED_PROVIDERS=("auth0/auth0")
1010
# Global variable for terraform version override
1111
TF_VERSION="latest"
1212

13+
# Global variable for lock-only mode
14+
LOCK_ONLY=false
15+
1316
# Function to check if a command is available
1417
check_command() {
1518
local cmd="$1"
@@ -21,11 +24,15 @@ check_command() {
2124

2225
# Function to get terraform version from versions.tf
2326
get_terraform_version() {
27+
check_command "hcl2json"
28+
check_command "jq"
2429
hcl2json versions.tf | jq -r '.terraform[0].required_version'
2530
}
2631

2732
# Function to get filtered providers using jq
2833
get_filtered_providers() {
34+
check_command "hcl2json"
35+
check_command "jq"
2936
# Convert bash array to jq array format for filtering
3037
local ignored_json
3138
ignored_json=$(printf '%s\n' "${IGNORED_PROVIDERS[@]}" | jq -R . | jq -s .)
@@ -41,6 +48,8 @@ get_filtered_providers() {
4148

4249
# Function to get provider info (source and version) for tracking changes
4350
get_provider_info() {
51+
check_command "hcl2json"
52+
check_command "jq"
4453
# Convert bash array to jq array format for filtering
4554
local ignored_json
4655
ignored_json=$(printf '%s\n' "${IGNORED_PROVIDERS[@]}" | jq -R . | jq -s .)
@@ -56,6 +65,7 @@ get_provider_info() {
5665

5766
# Function to update providers
5867
update_providers() {
68+
check_command "tfupdate"
5969
pushd "$SHARED_DIR" >/dev/null || exit 1
6070
echo "Updating providers..."
6171

@@ -114,6 +124,7 @@ update_providers() {
114124

115125
# Function to lock providers
116126
lock_providers() {
127+
check_command "tfupdate"
117128
echo "Locking providers..."
118129
tfupdate lock -r \
119130
--platform linux_arm64 \
@@ -126,6 +137,7 @@ lock_providers() {
126137

127138
# Function to update terraform
128139
update_terraform() {
140+
check_command "tfupdate"
129141
pushd "$SHARED_DIR" >/dev/null || exit 1
130142
echo "Updating terraform..."
131143

@@ -161,20 +173,25 @@ while [[ $# -gt 0 ]]; do
161173
TF_VERSION="$2"
162174
shift 2
163175
;;
176+
--lock-only)
177+
LOCK_ONLY=true
178+
shift
179+
;;
164180
*)
165-
echo "Usage: $0 [--tf-version VERSION]"
181+
echo "Usage: $0 [--tf-version VERSION] [--lock-only]"
166182
echo " --tf-version VERSION Set terraform to specific version (default: latest)"
183+
echo " --lock-only Only update provider locks, skip terraform and provider updates"
167184
echo " (no args) Update terraform, providers, and lock providers"
168185
exit 1
169186
;;
170187
esac
171188
done
172189

173-
# Check for required commands
174-
check_command "tfupdate"
175-
check_command "hcl2json"
176-
check_command "jq"
177-
178-
update_terraform
179-
update_providers
180-
lock_providers
190+
if [[ "$LOCK_ONLY" == "true" ]]; then
191+
echo "Running in lock-only mode..."
192+
lock_providers
193+
else
194+
update_terraform
195+
update_providers
196+
lock_providers
197+
fi

0 commit comments

Comments
 (0)