Skip to content

Commit 85297c6

Browse files
fix: update permissions and enhance container structure testing in workflows (#60)
* fix: update permissions and enhance container structure testing in workflows --------- Co-authored-by: ChristophShyper <45788587+ChristophShyper@users.noreply.github.com>
1 parent 9ec62f8 commit 85297c6

12 files changed

Lines changed: 228 additions & 92 deletions

.github/workflows/cron-check-dependencies.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ on:
66
workflow_dispatch:
77

88
permissions:
9-
contents: read
10-
issues: write
11-
pull-requests: read
9+
contents: write
10+
pull-requests: write
1211
packages: write
12+
issues: read
1313

1414
jobs:
1515
call-weekly-health-check:

.github/workflows/reusable-auto-create-pull-request.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
uses: arduino/setup-task@v2.0.0
4747
with:
4848
version: ${{ inputs.task-version }}
49+
repo-token: ${{ secrets.GITHUB_TOKEN }}
4950

5051
- name: Get template
5152
env:
@@ -77,6 +78,7 @@ jobs:
7778
uses: arduino/setup-task@v2.0.0
7879
with:
7980
version: ${{ inputs.task-version }}
81+
repo-token: ${{ secrets.GITHUB_TOKEN }}
8082

8183
- name: Run linters
8284
run: task lint
@@ -96,6 +98,7 @@ jobs:
9698
uses: arduino/setup-task@v2.0.0
9799
with:
98100
version: ${{ inputs.task-version }}
101+
repo-token: ${{ secrets.GITHUB_TOKEN }}
99102

100103
- name: Install Docker Buildx
101104
uses: docker/setup-buildx-action@v4
@@ -117,3 +120,39 @@ jobs:
117120
env:
118121
VERSION_SUFFIX: '-test'
119122
run: task docker:push:inspect
123+
124+
- name: Detect container structure test configs
125+
id: cst-configs
126+
run: |
127+
shopt -s nullglob
128+
files=(tests/docker/*.yml tests/docker/*.yaml)
129+
if [ "${#files[@]}" -eq 0 ]; then
130+
echo "has_tests=false" >> "$GITHUB_OUTPUT"
131+
exit 0
132+
fi
133+
printf '%s\n' "${files[@]}" | sort > "$RUNNER_TEMP/cst-configs.txt"
134+
{
135+
echo "has_tests=true"
136+
echo "config<<EOF"
137+
cat "$RUNNER_TEMP/cst-configs.txt"
138+
echo "EOF"
139+
} >> "$GITHUB_OUTPUT"
140+
141+
- name: Resolve CST image
142+
id: cst-image
143+
if: steps.cst-configs.outputs.has_tests == 'true'
144+
run: |
145+
if task --list | grep -q "docker:image:test:ref"; then
146+
IMAGE_REF="$(task docker:image:test:ref)"
147+
else
148+
VERSION="$(task version:get)"
149+
IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test"
150+
fi
151+
echo "image=$IMAGE_REF" >> "$GITHUB_OUTPUT"
152+
153+
- name: Run container structure tests
154+
if: steps.cst-configs.outputs.has_tests == 'true'
155+
uses: devops-infra/action-container-structure-test@v1
156+
with:
157+
image: ${{ steps.cst-image.outputs.image }}
158+
config: ${{ steps.cst-configs.outputs.config }}

.github/workflows/reusable-cron-check-dependencies.yml

Lines changed: 118 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,18 @@ on:
2424
type: string
2525
default: actions
2626
stale-days:
27-
description: Mark branches/issues stale after this many days
27+
description: Mark branches/pull requests/issues stale after this many days
2828
type: number
2929
default: 60
30-
issue-title:
31-
description: Issue title for weekly report
32-
type: string
33-
default: (Weekly) Repository health report
34-
issue-labels:
35-
description: Comma-separated labels for weekly report issue
36-
type: string
37-
default: automation,dependencies
3830
secrets:
3931
DOCKER_TOKEN:
4032
required: false
4133

4234
permissions:
43-
contents: read
44-
issues: write
45-
pull-requests: read
35+
contents: write
36+
pull-requests: write
4637
packages: write
38+
issues: read
4739

4840
jobs:
4941
dependency-check:
@@ -60,11 +52,11 @@ jobs:
6052
uses: arduino/setup-task@v2.0.0
6153
with:
6254
version: ${{ inputs.task-version }}
55+
repo-token: ${{ secrets.GITHUB_TOKEN }}
6356

6457
- name: Prepare report workspace
6558
run: |
66-
mkdir -p .tmp
67-
: > .tmp/findings.md
59+
REPORT_FILE="${RUNNER_TEMP}/weekly-health-report.md"
6860
{
6961
echo "## Weekly Health Report"
7062
echo ""
@@ -73,8 +65,10 @@ jobs:
7365
echo "- Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
7466
echo "- Generated: $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
7567
echo ""
76-
echo "### Findings"
77-
} > .tmp/report.md
68+
echo "### Important findings"
69+
} > "$REPORT_FILE"
70+
echo "REPORT_FILE=$REPORT_FILE" >> "$GITHUB_ENV"
71+
echo "HAS_FINDINGS=false" >> "$GITHUB_ENV"
7872
7973
- name: Run lint
8074
id: lint
@@ -84,25 +78,9 @@ jobs:
8478

8579
- name: Record lint findings
8680
if: inputs.enable-lint && steps.lint.outcome != 'success'
87-
run: echo "- [lint] \`task lint\` failed" >> .tmp/findings.md
88-
89-
- name: Validate baseline
90-
id: baseline
91-
continue-on-error: true
9281
run: |
93-
set -eu
94-
[ -f Taskfile.yml ] || { echo "Taskfile.yml missing"; exit 1; }
95-
[ -f .github/workflows/auto-create-pull-request.yml ] || { echo "Missing workflow: auto-create-pull-request.yml"; exit 1; }
96-
[ -f .github/workflows/cron-check-dependencies.yml ] || { echo "Missing workflow: cron-check-dependencies.yml"; exit 1; }
97-
[ -f .github/workflows/manual-update-version.yml ] || { echo "Missing workflow: manual-update-version.yml"; exit 1; }
98-
if grep -R -n -E "uses:[[:space:]]+.+@master" .github/workflows >/dev/null 2>&1; then
99-
echo "Found @master workflow references in caller workflows"
100-
exit 1
101-
fi
102-
103-
- name: Record baseline findings
104-
if: steps.baseline.outcome != 'success'
105-
run: echo "- [baseline] Required files are missing or caller workflows still reference \`@master\`" >> .tmp/findings.md
82+
echo "- lint failed: \`task lint\`" >> "$REPORT_FILE"
83+
echo "HAS_FINDINGS=true" >> "$GITHUB_ENV"
10684
10785
- name: Run dependency checks
10886
id: deps
@@ -124,7 +102,9 @@ jobs:
124102
125103
- name: Record dependency findings
126104
if: steps.deps.outcome != 'success'
127-
run: echo "- [dependencies] Dependency check reported updates or failed" >> .tmp/findings.md
105+
run: |
106+
echo "- dependency checks reported updates or failed" >> "$REPORT_FILE"
107+
echo "HAS_FINDINGS=true" >> "$GITHUB_ENV"
128108
129109
- name: Install Docker Buildx
130110
if: inputs.profile == 'actions' || inputs.profile == 'dockerized'
@@ -149,11 +129,60 @@ jobs:
149129
task docker:push
150130
task docker:push:inspect
151131
132+
- name: Detect container structure test configs
133+
id: cst-configs
134+
if: inputs.profile == 'actions' || inputs.profile == 'dockerized'
135+
continue-on-error: true
136+
run: |
137+
shopt -s nullglob
138+
files=(tests/docker/*.yml tests/docker/*.yaml)
139+
if [ "${#files[@]}" -eq 0 ]; then
140+
echo "has_tests=false" >> "$GITHUB_OUTPUT"
141+
exit 0
142+
fi
143+
printf '%s\n' "${files[@]}" | sort > "$RUNNER_TEMP/cst-configs.txt"
144+
{
145+
echo "has_tests=true"
146+
echo "config<<EOF"
147+
cat "$RUNNER_TEMP/cst-configs.txt"
148+
echo "EOF"
149+
} >> "$GITHUB_OUTPUT"
150+
151+
- name: Resolve CST image
152+
id: cst-image
153+
if: (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.cst-configs.outputs.has_tests == 'true'
154+
continue-on-error: true
155+
run: |
156+
if task --list | grep -q "docker:image:test:ref"; then
157+
IMAGE_REF="$(task docker:image:test:ref)"
158+
else
159+
VERSION="$(task version:get)"
160+
IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test"
161+
fi
162+
echo "image=$IMAGE_REF" >> "$GITHUB_OUTPUT"
163+
164+
- name: Run container structure tests
165+
id: cst
166+
if: (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.cst-configs.outputs.has_tests == 'true'
167+
continue-on-error: true
168+
uses: devops-infra/action-container-structure-test@v1
169+
with:
170+
image: ${{ steps.cst-image.outputs.image }}
171+
config: ${{ steps.cst-configs.outputs.config }}
172+
152173
- name: Record docker findings
153174
if: (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.docker.outcome != 'success'
154-
run: echo "- [docker] Docker validation failed (build/push/inspect)" >> .tmp/findings.md
175+
run: |
176+
echo "- docker build/push/inspect failed" >> "$REPORT_FILE"
177+
echo "HAS_FINDINGS=true" >> "$GITHUB_ENV"
178+
179+
- name: Record container structure test findings
180+
if: (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.cst-configs.outputs.has_tests == 'true' && steps.cst.outcome != 'success'
181+
run: |
182+
echo "- container structure tests failed for tests/docker configs" >> "$REPORT_FILE"
183+
echo "HAS_FINDINGS=true" >> "$GITHUB_ENV"
155184
156-
- name: Detect stale branches and issues
185+
- name: Detect stale branches, pull requests, and issues
157186
id: stale
158187
uses: actions/github-script@v9
159188
with:
@@ -170,6 +199,12 @@ jobs:
170199
const commitDate = new Date(commit.data.commit.committer.date).getTime()
171200
if (now - commitDate > staleMs) staleBranches.push(branch.name)
172201
}
202+
const stalePullRequests = []
203+
const pullRequests = await github.paginate(github.rest.pulls.list, { owner: context.repo.owner, repo: context.repo.repo, state: 'open', per_page: 100 })
204+
for (const pullRequest of pullRequests) {
205+
const updated = new Date(pullRequest.updated_at).getTime()
206+
if (now - updated > staleMs) stalePullRequests.push(`#${pullRequest.number}`)
207+
}
173208
const staleIssues = []
174209
const issues = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, repo: context.repo.repo, state: 'open', per_page: 100 })
175210
for (const issue of issues) {
@@ -178,57 +213,67 @@ jobs:
178213
if (now - updated > staleMs) staleIssues.push(`#${issue.number}`)
179214
}
180215
core.setOutput('stale_branch_count', String(staleBranches.length))
216+
core.setOutput('stale_pr_count', String(stalePullRequests.length))
181217
core.setOutput('stale_issue_count', String(staleIssues.length))
182218
core.setOutput('stale_branches', staleBranches.slice(0, 20).join(', '))
219+
core.setOutput('stale_prs', stalePullRequests.slice(0, 20).join(', '))
183220
core.setOutput('stale_issues', staleIssues.slice(0, 20).join(', '))
184221
185222
- name: Record stale findings
186-
if: steps.stale.outputs.stale_branch_count != '0' || steps.stale.outputs.stale_issue_count != '0'
223+
if: steps.stale.outputs.stale_branch_count != '0' || steps.stale.outputs.stale_pr_count != '0' || steps.stale.outputs.stale_issue_count != '0'
187224
run: |
188225
if [ "${{ steps.stale.outputs.stale_branch_count }}" != "0" ]; then
189-
echo "- [stale-branches] Found ${{ steps.stale.outputs.stale_branch_count }} stale branches: ${{ steps.stale.outputs.stale_branches }}" >> .tmp/findings.md
226+
echo "- stale branches (${{ steps.stale.outputs.stale_branch_count }}): ${{ steps.stale.outputs.stale_branches }}" >> "$REPORT_FILE"
227+
fi
228+
if [ "${{ steps.stale.outputs.stale_pr_count }}" != "0" ]; then
229+
echo "- stale pull requests (${{ steps.stale.outputs.stale_pr_count }}): ${{ steps.stale.outputs.stale_prs }}" >> "$REPORT_FILE"
190230
fi
191231
if [ "${{ steps.stale.outputs.stale_issue_count }}" != "0" ]; then
192-
echo "- [stale-issues] Found ${{ steps.stale.outputs.stale_issue_count }} stale issues: ${{ steps.stale.outputs.stale_issues }}" >> .tmp/findings.md
232+
echo "- stale issues (${{ steps.stale.outputs.stale_issue_count }}): ${{ steps.stale.outputs.stale_issues }}" >> "$REPORT_FILE"
193233
fi
234+
echo "HAS_FINDINGS=true" >> "$GITHUB_ENV"
194235
195236
- name: Finalize report
196237
id: report
197238
run: |
198-
if [ -s .tmp/findings.md ]; then
199-
cat .tmp/findings.md >> .tmp/report.md
200-
echo "status=issues" >> "$GITHUB_OUTPUT"
239+
if [ "$HAS_FINDINGS" != "true" ]; then
240+
echo "- no important updates or breaking changes detected" >> "$REPORT_FILE"
241+
fi
242+
243+
- name: Detect repository changes
244+
id: changes
245+
run: |
246+
if [ -n "$(git status --porcelain)" ]; then
247+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
201248
else
202-
echo "- No findings. Repository matches current baseline." >> .tmp/report.md
203-
echo "status=clean" >> "$GITHUB_OUTPUT"
249+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
204250
fi
205251
206-
- name: Create or update weekly issue
207-
uses: actions/github-script@v9
208-
env:
209-
ISSUE_TITLE: ${{ inputs.issue-title }}
210-
ISSUE_LABELS: ${{ inputs.issue-labels }}
211-
REPORT_STATUS: ${{ steps.report.outputs.status }}
252+
- name: Commit and push changes
253+
id: commit
254+
if: steps.changes.outputs.has_changes == 'true'
255+
run: |
256+
git config user.name "github-actions[bot]"
257+
git config user.email "github-actions[bot]@users.noreply.github.com"
258+
BRANCH_NAME="chore/weekly-health-${GITHUB_RUN_ID}"
259+
git checkout -B "$BRANCH_NAME"
260+
git add -A
261+
git commit -m "chore: weekly dependency and health updates" -m "$(cat "$REPORT_FILE")"
262+
git push --set-upstream origin "$BRANCH_NAME"
263+
{
264+
echo "branch_name=$BRANCH_NAME"
265+
echo "report_body<<EOF"
266+
cat "$REPORT_FILE"
267+
echo "EOF"
268+
} >> "$GITHUB_OUTPUT"
269+
270+
- name: Create pull request
271+
if: steps.changes.outputs.has_changes == 'true'
272+
uses: devops-infra/action-pull-request@v1
212273
with:
213-
script: |
214-
const fs = require('fs')
215-
const title = process.env.ISSUE_TITLE
216-
const labels = process.env.ISSUE_LABELS.split(',').map(v => v.trim()).filter(Boolean)
217-
const status = process.env.REPORT_STATUS
218-
const body = fs.readFileSync('.tmp/report.md', 'utf8')
219-
const repoLabels = await github.paginate(github.rest.issues.listLabelsForRepo, { owner: context.repo.owner, repo: context.repo.repo, per_page: 100 })
220-
const repoLabelSet = new Set(repoLabels.map(l => l.name))
221-
const safeLabels = labels.filter(l => repoLabelSet.has(l))
222-
const openIssues = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, repo: context.repo.repo, state: 'open', per_page: 100 })
223-
const existing = openIssues.find(i => i.title === title)
224-
if (status === 'clean') {
225-
if (existing) {
226-
await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: existing.number, body, state: 'closed', state_reason: 'completed' })
227-
}
228-
return
229-
}
230-
if (existing) {
231-
await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: existing.number, body })
232-
} else {
233-
await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title, body, labels: safeLabels })
234-
}
274+
github_token: ${{ github.token }}
275+
source_branch: ${{ steps.commit.outputs.branch_name }}
276+
target_branch: ${{ github.event.repository.default_branch }}
277+
title: "chore: weekly dependency and health updates"
278+
body: ${{ steps.commit.outputs.report_body }}
279+
assignee: ${{ github.actor }}

.github/workflows/reusable-manual-sync-common-files.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
uses: arduino/setup-task@v2.0.0
4040
with:
4141
version: ${{ inputs.task-version }}
42+
repo-token: ${{ secrets.GITHUB_TOKEN }}
4243

4344
- name: Sync files and get PR template
4445
id: sync

0 commit comments

Comments
 (0)