Skip to content

Commit 6790a4d

Browse files
perf(ci): reuse build artifacts across PR checks
1 parent bac46c1 commit 6790a4d

9 files changed

Lines changed: 440 additions & 263 deletions

File tree

.github/actions/setup-caches/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ runs:
3737
3838
- name: Compute Playwright cache identity
3939
id: playwright-identity
40-
if: inputs.cache-type == 'webapp-storybook'
40+
if: contains(fromJSON('["webapp-storybook", "webapp-e2e"]'), inputs.cache-type)
4141
shell: bash
4242
env:
4343
DEPENDENCY_HASH: ${{ hashFiles('bun.lock') }}
@@ -78,7 +78,7 @@ runs:
7878
key: ${{ inputs.os }}-${{ steps.java.outputs.distribution }}-${{ steps.java.outputs.version }}-generated-clients-${{ steps.generated-clients-identity.outputs.hash }}
7979

8080
- name: Cache Playwright browsers
81-
if: inputs.cache-type == 'webapp-storybook'
81+
if: contains(fromJSON('["webapp-storybook", "webapp-e2e"]'), inputs.cache-type)
8282
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
8383
with:
8484
path: ~/.cache/ms-playwright

.github/workflows/ci-quality-gates.yml

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ on:
1818
required: false
1919
type: string
2020
default: "true"
21+
tooling_changed:
22+
description: "Whether repository tooling, docs, or instruction files changed"
23+
required: false
24+
type: string
25+
default: "true"
26+
postgres_image_changed:
27+
description: "Whether the PostgreSQL image inputs changed"
28+
required: false
29+
type: string
30+
default: "false"
31+
contracts_changed:
32+
description: "Whether server contracts or their PostgreSQL image changed"
33+
required: false
34+
type: string
35+
default: "true"
2136
pmd_canary:
2237
description: "Whether PMD wiring inputs changed"
2338
required: false
@@ -39,6 +54,8 @@ jobs:
3954
include:
4055
- check: application-server-quality
4156
display-name: "App Server"
57+
- check: tooling-quality
58+
display-name: "Tooling and Docs"
4259
- check: webapp-quality
4360
display-name: "Webapp"
4461
- check: server-contracts
@@ -51,9 +68,15 @@ jobs:
5168
"webapp-quality")
5269
echo "run=${{ inputs.webapp_changed }}" >> $GITHUB_OUTPUT
5370
;;
54-
"application-server-quality"|"server-contracts")
71+
"application-server-quality")
5572
echo "run=${{ inputs.application_server_changed }}" >> $GITHUB_OUTPUT
5673
;;
74+
"server-contracts")
75+
echo "run=${{ inputs.contracts_changed }}" >> $GITHUB_OUTPUT
76+
;;
77+
"tooling-quality")
78+
echo "run=${{ inputs.tooling_changed }}" >> $GITHUB_OUTPUT
79+
;;
5780
*)
5881
echo "::error::Unknown check type '${{ matrix.check }}' in ci-quality-gates.yml matrix."
5982
echo "::error::Please add a case for this check in the 'Determine if check should run' step."
@@ -93,15 +116,12 @@ jobs:
93116
cache-type: server-contracts
94117
os: ${{ runner.os }}
95118

96-
- name: Application-server formatting + agent runtime + contracts
119+
- name: Application-server quality
97120
if: steps.should_run.outputs.run == 'true' && matrix.check == 'application-server-quality'
98121
run: |
99122
bun install --frozen-lockfile
100-
bun run check:package-manager
101-
bun run check:agent-runtime-pins
102-
103123
ISSUES_FOUND=()
104-
SERVER_OK=true; PMD_CANARY_OK=true; NULLNESS_OK=true; TOOLING_OK=true; TESTS_OK=true; CONTRACTS_OK=true; ENV_OK=true; DOCS_OK=true; DIAGRAMS_OK=true; INSTRUCTIONS_OK=true
124+
SERVER_OK=true; PMD_CANARY_OK=true; NULLNESS_OK=true; CONTRACTS_OK=true; ENV_OK=true
105125
106126
bun run check:server || { SERVER_OK=false; ISSUES_FOUND+=("Server formatting or PMD failed. Run: bun run check:server"); }
107127
bun run check:java-nullness \
@@ -118,26 +138,8 @@ jobs:
118138
cp "$RUNNER_TEMP/Application.java" "$PMD_CANARY"
119139
trap - EXIT
120140
fi
121-
bun run check:agents \
122-
|| { TOOLING_OK=false; ISSUES_FOUND+=("Repository tooling checks failed. Run: bun run check:agents"); }
123-
bun run test:agents \
124-
|| { TESTS_OK=false; ISSUES_FOUND+=("Agent runtime test(s) failed. Run: bun run test:agents"); }
125141
bun run check:contracts || { CONTRACTS_OK=false; ISSUES_FOUND+=("Artifact-source contract validation failed. Run: bun run check:contracts"); }
126-
# Reads server/application.yml against docker/compose.{app,core}.yaml — the deployment that
127-
# has to deliver each setting. Both sides are behind this job's path filter.
128142
bun run check:env || { ENV_OK=false; ISSUES_FOUND+=("A setting does not reach a container that can read it. Run: bun run check:env"); }
129-
# An AGENTS.md no CLAUDE.md imports is loaded by every agent except Claude Code, and nothing
130-
# about the file says so — this is the only place that reads the wiring end to end.
131-
bun run check:instructions \
132-
|| { INSTRUCTIONS_OK=false; ISSUES_FOUND+=("An agent instruction file reaches no agent, or exists in two copies. Run: bun run check:instructions"); }
133-
# docs/decisions/ and docs/runbooks/ are mounted by no Docusaurus plugin, so the site build
134-
# never compiles or link-checks them. Markdown lint is the only gate they have.
135-
bun run docs:lint || { DOCS_OK=false; ISSUES_FOUND+=("docs/ markdown or typecheck failed. Run: bun run docs:lint"); }
136-
# Docusaurus renders mermaid in the browser, so a diagram it cannot parse builds green and
137-
# publishes as an error box — the docs deployment can never be the gate for it. This leg
138-
# owns the check because docs/** is behind this job's path filter and no other job's.
139-
bun run check:diagrams \
140-
|| { DIAGRAMS_OK=false; ISSUES_FOUND+=("A committed Mermaid diagram does not parse. Run: bun run check:diagrams"); }
141143
142144
if [ ${#ISSUES_FOUND[@]} -gt 0 ]; then
143145
echo "### App Server Quality" >> $GITHUB_STEP_SUMMARY
@@ -146,17 +148,24 @@ jobs:
146148
[[ "$SERVER_OK" == "false" ]] && echo "| Server formatting and PMD | :x: Failed | \`bun run check:server\` |" >> $GITHUB_STEP_SUMMARY
147149
[[ "$PMD_CANARY_OK" == "false" ]] && echo "| PMD canary | :x: Failed | Inspect the planted-violation check |" >> $GITHUB_STEP_SUMMARY
148150
[[ "$NULLNESS_OK" == "false" ]] && echo "| Java nullness policy | :x: Failed | \`bun run check:java-nullness\` |" >> $GITHUB_STEP_SUMMARY
149-
[[ "$TOOLING_OK" == "false" ]] && echo "| Repository tooling | :x: Failed | \`bun run check:agents\` |" >> $GITHUB_STEP_SUMMARY
150-
[[ "$TESTS_OK" == "false" ]] && echo "| Agent runtime tests | :x: Failed | \`bun run test:agents\` |" >> $GITHUB_STEP_SUMMARY
151151
[[ "$CONTRACTS_OK" == "false" ]] && echo "| Artifact-source contracts | :x: Failed | \`bun run check:contracts\` |" >> $GITHUB_STEP_SUMMARY
152152
[[ "$ENV_OK" == "false" ]] && echo "| Env delivery by runtime role | :x: Failed | \`bun run check:env\` |" >> $GITHUB_STEP_SUMMARY
153-
[[ "$INSTRUCTIONS_OK" == "false" ]] && echo "| Agent instruction wiring | :x: Failed | \`bun run check:instructions\` |" >> $GITHUB_STEP_SUMMARY
154-
[[ "$DOCS_OK" == "false" ]] && echo "| Docs lint + typecheck | :x: Failed | \`bun run docs:lint\` |" >> $GITHUB_STEP_SUMMARY
155-
[[ "$DIAGRAMS_OK" == "false" ]] && echo "| Mermaid diagrams | :x: Failed | \`bun run check:diagrams\` |" >> $GITHUB_STEP_SUMMARY
156153
for issue in "${ISSUES_FOUND[@]}"; do echo "::error::$issue"; done
157154
exit 1
158155
fi
159156
157+
- name: Tooling and docs quality
158+
if: steps.should_run.outputs.run == 'true' && matrix.check == 'tooling-quality'
159+
run: |
160+
bun install --frozen-lockfile
161+
bun run check:package-manager
162+
bun run check:agent-runtime-pins
163+
bun run check:agents
164+
bun run test:agents
165+
bun run check:instructions
166+
bun run docs:lint
167+
bun run check:diagrams
168+
160169
- name: Webapp quality
161170
if: steps.should_run.outputs.run == 'true' && matrix.check == 'webapp-quality'
162171
working-directory: ./webapp
@@ -257,10 +266,12 @@ jobs:
257266
continue-on-error: true
258267
if: steps.should_run.outputs.run == 'true' && matrix.check == 'server-contracts' && always()
259268
run: |
260-
# The pg_partman image, not stock Postgres: the auth_event changeset that calls
261-
# partman.create_parent is preconditioned onFail="MARK_RAN" on the extension being
262-
# available, so on a stock image the chain replays with that changeset never executed.
263-
docker build -t hephaestus-postgres:ci docker/postgres
269+
if [[ "${{ inputs.postgres_image_changed }}" == "true" ]]; then
270+
docker build -t hephaestus-postgres:ci docker/postgres
271+
else
272+
docker pull ghcr.io/ls1intum/hephaestus/postgres:${{ github.event.pull_request.base.sha || github.sha }}
273+
docker tag ghcr.io/ls1intum/hephaestus/postgres:${{ github.event.pull_request.base.sha || github.sha }} hephaestus-postgres:ci
274+
fi
264275
docker run -d --name postgres-db \
265276
-e POSTGRES_DB=hephaestus -e POSTGRES_PASSWORD=root -e POSTGRES_USER=root \
266277
-p 5432:5432 hephaestus-postgres:ci

0 commit comments

Comments
 (0)