Skip to content

Commit 0b9391d

Browse files
author
Sean Thomas
committed
Add plan/apply flow with GitHub issue notifications
1 parent 456559c commit 0b9391d

1 file changed

Lines changed: 107 additions & 3 deletions

File tree

.github/workflows/renew-tls-certificates.yml

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,20 @@ on:
1414
description: "Network to renew certificates for (leave empty for all)"
1515
required: false
1616
type: string
17+
apply:
18+
description: "Set to true to apply the renewal (default is plan only)"
19+
required: false
20+
type: boolean
21+
default: false
1722

1823
permissions:
1924
contents: read
2025
id-token: write
26+
issues: write
2127

2228
jobs:
23-
renew-certs:
24-
name: Renew certs (${{ matrix.network_name }})
29+
check-certs:
30+
name: "${{ inputs.apply && 'Apply' || 'Plan' }} (${{ matrix.network_name }})"
2531
runs-on: ubuntu-latest
2632
strategy:
2733
fail-fast: false
@@ -72,12 +78,110 @@ jobs:
7278
if: steps.check.outputs.skip != 'true'
7379
run: ./bin/terraform-init infra/networks "${{ matrix.network_name }}"
7480

75-
- name: Renew certificates
81+
- name: Plan certificate renewal
82+
id: plan
7683
if: steps.check.outputs.skip != 'true'
7784
run: |
85+
set +e
7886
terraform -chdir=infra/networks plan \
7987
-var="network_name=${{ matrix.network_name }}" \
8088
-target='module.domain' \
89+
-input=false \
90+
-detailed-exitcode \
91+
-no-color 2>&1 | tee /tmp/plan-output.txt
92+
exit_code=$?
93+
set -e
94+
95+
if [[ $exit_code -eq 2 ]]; then
96+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
97+
summary=$(grep -E "^Plan:" /tmp/plan-output.txt || echo "Changes detected")
98+
echo "summary=$summary" >> "$GITHUB_OUTPUT"
99+
elif [[ $exit_code -eq 0 ]]; then
100+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
101+
else
102+
echo "Plan failed with exit code $exit_code"
103+
exit $exit_code
104+
fi
105+
env:
106+
ARM_USE_OIDC: true
107+
108+
- name: Create issue for review
109+
if: steps.plan.outputs.has_changes == 'true' && !inputs.apply
110+
uses: actions/github-script@v7
111+
with:
112+
script: |
113+
const network = '${{ matrix.network_name }}';
114+
const summary = `${{ steps.plan.outputs.summary }}`;
115+
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
116+
const today = new Date().toISOString().slice(0, 10);
117+
118+
// Check for an existing open issue for this network to avoid duplicates
119+
const existing = await github.rest.issues.listForRepo({
120+
owner: context.repo.owner,
121+
repo: context.repo.repo,
122+
state: 'open',
123+
labels: 'tls-renewal',
124+
per_page: 100,
125+
});
126+
const duplicate = existing.data.find(i => i.title.includes(`(${network})`));
127+
if (duplicate) {
128+
console.log(`Open issue already exists: #${duplicate.number}`);
129+
return;
130+
}
131+
132+
await github.rest.issues.create({
133+
owner: context.repo.owner,
134+
repo: context.repo.repo,
135+
title: `TLS certificate renewal needed (${network})`,
136+
body: [
137+
`## TLS Certificate Renewal — ${network}`,
138+
'',
139+
`The monthly check found certificates that need renewal in the **${network}** network.`,
140+
'',
141+
`**${summary}**`,
142+
'',
143+
`[View plan output](${runUrl})`,
144+
'',
145+
'### To apply the renewal',
146+
'',
147+
'Go to **Actions > Renew TLS Certificates > Run workflow** and set:',
148+
`- \`network_name\` = \`${network}\``,
149+
'- `apply` = `true`',
150+
].join('\n'),
151+
labels: ['tls-renewal'],
152+
});
153+
154+
- name: Renew certificates
155+
if: steps.plan.outputs.has_changes == 'true' && inputs.apply
156+
run: |
157+
terraform -chdir=infra/networks apply \
158+
-var="network_name=${{ matrix.network_name }}" \
159+
-target='module.domain' \
160+
-auto-approve \
81161
-input=false
82162
env:
83163
ARM_USE_OIDC: true
164+
165+
- name: Close renewal issue
166+
if: steps.plan.outputs.has_changes == 'true' && inputs.apply && success()
167+
uses: actions/github-script@v7
168+
with:
169+
script: |
170+
const network = '${{ matrix.network_name }}';
171+
const issues = await github.rest.issues.listForRepo({
172+
owner: context.repo.owner,
173+
repo: context.repo.repo,
174+
state: 'open',
175+
labels: 'tls-renewal',
176+
per_page: 100,
177+
});
178+
const issue = issues.data.find(i => i.title.includes(`(${network})`));
179+
if (issue) {
180+
await github.rest.issues.update({
181+
owner: context.repo.owner,
182+
repo: context.repo.repo,
183+
issue_number: issue.number,
184+
state: 'closed',
185+
state_reason: 'completed',
186+
});
187+
}

0 commit comments

Comments
 (0)