Skip to content

Commit b81a368

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 c54bd64 commit b81a368

2 files changed

Lines changed: 211 additions & 10 deletions

File tree

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

infra/scripts/upgrade_tf_version.sh

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

14+
# Global variable for lock-only mode
15+
LOCK_ONLY=false
16+
1417
# Function to check if a command is available
1518
check_command() {
1619
local cmd="$1"
@@ -22,11 +25,15 @@ check_command() {
2225

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

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

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

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

@@ -115,12 +125,14 @@ update_providers() {
115125

116126
# Function to lock providers
117127
lock_providers() {
128+
check_command "tfupdate"
118129
echo "Locking providers..."
119130
tfupdate lock -r --platform linux_arm64 --platform linux_amd64 --platform darwin_amd64 --platform windows_amd64 -i infra/shared infra/
120131
}
121132

122133
# Function to update terraform
123134
update_terraform() {
135+
check_command "tfupdate"
124136
pushd "$SHARED_DIR" >/dev/null || exit 1
125137
echo "Updating terraform..."
126138

@@ -156,21 +168,25 @@ while [[ $# -gt 0 ]]; do
156168
TF_VERSION="$2"
157169
shift 2
158170
;;
171+
--lock-only)
172+
LOCK_ONLY=true
173+
shift
174+
;;
159175
*)
160-
echo "Usage: $0 [--tf-version VERSION]"
176+
echo "Usage: $0 [--tf-version VERSION] [--lock-only]"
161177
echo " --tf-version VERSION Set terraform to specific version (default: latest)"
178+
echo " --lock-only Only update provider locks, skip terraform and provider updates"
162179
echo " (no args) Update terraform, providers, and lock providers"
163180
exit 1
164181
;;
165182
esac
166183
done
167184

168-
169-
# Check for required commands
170-
check_command "tfupdate"
171-
check_command "hcl2json"
172-
check_command "jq"
173-
174-
update_terraform
175-
update_providers
176-
lock_providers
185+
if [[ "$LOCK_ONLY" == "true" ]]; then
186+
echo "Running in lock-only mode..."
187+
lock_providers
188+
else
189+
update_terraform
190+
update_providers
191+
lock_providers
192+
fi

0 commit comments

Comments
 (0)