Skip to content

Commit 6af4ad2

Browse files
committed
ci: scope-aware build matrix
1 parent 8064283 commit 6af4ad2

13 files changed

Lines changed: 1097 additions & 361 deletions

.github/workflows/ci-build.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ jobs:
158158
github-token: ${{ secrets.GITHUB_TOKEN }}
159159

160160
- name: Process Coverage
161+
id: process-coverage
161162
if: matrix.coverage == 'true'
162163
uses: alandefreitas/cpp-actions/process-coverage@v1.9.4
163164
with:
@@ -166,3 +167,19 @@ jobs:
166167
html-report: true
167168
codecov-token: ${{ secrets.CODECOV_TOKEN }}
168169
codecov-flags: cpp
170+
171+
# Save the produced LCOV report so PRs that don't change source files
172+
# can replay it to codecov without re-running a Coverage build.
173+
# `ci-scope-detector.yml` probes this artifact by name and merge-base SHA.
174+
- name: Save coverage for replay
175+
if: |
176+
matrix.coverage == 'true' &&
177+
github.event_name == 'push' &&
178+
github.ref_name == 'develop' &&
179+
steps.process-coverage.outputs.lcov-file != ''
180+
uses: actions/upload-artifact@v4
181+
with:
182+
name: coverage-develop
183+
path: ${{ steps.process-coverage.outputs.lcov-file }}
184+
retention-days: 90
185+
if-no-files-found: error
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#
2+
# Licensed under the Apache License v2.0 with LLVM Exceptions.
3+
# See https://llvm.org/LICENSE.txt for license information.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#
6+
# Copyright (c) 2026 Alan de Freitas (alandefreitas@gmail.com)
7+
#
8+
# Official repository: https://github.com/cppalliance/mrdocs
9+
#
10+
# Per-OS validation that the docs/website/Antora-UI pipelines build
11+
# cleanly with the installed mrdocs binary. Scope-gated: runs when
12+
# source, docs, build, or third-party files changed (i.e. anything
13+
# that can influence rendered documentation). Skipped on tooling /
14+
# ci / toolchain-only PRs.
15+
16+
name: Documentation
17+
18+
on:
19+
workflow_call:
20+
inputs:
21+
submatrix:
22+
description: 'JSON-encoded releases submatrix from cpp-matrix'
23+
type: string
24+
required: true
25+
use-develop-binaries:
26+
description: 'true to fetch packages from develop-release instead of this run'
27+
type: boolean
28+
default: false
29+
30+
jobs:
31+
documentation:
32+
strategy:
33+
fail-fast: false
34+
matrix:
35+
include: ${{ fromJSON(inputs.submatrix) }}
36+
37+
defaults:
38+
run:
39+
shell: bash
40+
41+
name: ${{ matrix.os }}
42+
runs-on: ${{ matrix.runs-on }}
43+
container: ${{ matrix.container }}
44+
permissions:
45+
contents: read
46+
steps:
47+
- name: Container Bootstrap
48+
uses: alandefreitas/cpp-actions/container-bootstrap@v1.9.4
49+
50+
- name: Install packages
51+
uses: alandefreitas/cpp-actions/package-install@v1.9.4
52+
with:
53+
apt-get: build-essential asciidoctor cmake bzip2 git rsync
54+
55+
- name: Clone MrDocs
56+
uses: actions/checkout@v4
57+
with:
58+
fetch-depth: 1
59+
60+
- name: Install Node.js
61+
uses: actions/setup-node@v4
62+
with:
63+
node-version: '20'
64+
65+
- name: Setup C++
66+
uses: alandefreitas/cpp-actions/setup-cpp@v1.9.4
67+
id: setup-cpp
68+
with:
69+
compiler: ${{ matrix.compiler }}
70+
version: ${{ matrix.version }}
71+
72+
# Same dual-source pattern as ci-release.yml: fresh-build artifact
73+
# when we built this run, develop-release fallback otherwise.
74+
- name: Download MrDocs package (fresh build)
75+
if: ${{ !inputs.use-develop-binaries }}
76+
uses: actions/download-artifact@v4
77+
with:
78+
name: ${{ matrix.mrdocs-release-package-artifact }}
79+
path: packages
80+
81+
- name: Download MrDocs package (develop-release fallback)
82+
if: ${{ inputs.use-develop-binaries }}
83+
env:
84+
GH_TOKEN: ${{ github.token }}
85+
run: |
86+
set -euo pipefail
87+
mkdir -p packages
88+
case "${{ runner.os }}" in
89+
Linux) pattern='*Linux*' ;;
90+
Windows) pattern='*Windows*' ;;
91+
macOS) pattern='*Darwin*' ;;
92+
*) echo "::error::unknown runner.os: ${{ runner.os }}"; exit 1 ;;
93+
esac
94+
gh release download develop-release --pattern "$pattern" -D packages
95+
96+
- name: Install MrDocs from Package
97+
run: .github/scripts/install-mrdocs-package.sh
98+
99+
- name: Generate Landing Page
100+
working-directory: docs/website
101+
run: |
102+
npm ci
103+
node render.js
104+
mkdir -p ../../build/website
105+
cp index.html ../../build/website/index.html
106+
cp robots.txt ../../build/website/robots.txt
107+
cp styles.css ../../build/website/styles.css
108+
cp -r assets ../../build/website/assets
109+
110+
- name: Generate Antora UI
111+
working-directory: docs/ui
112+
run: |
113+
GH_TOKEN="${{ secrets.GITHUB_TOKEN }}"
114+
export GH_TOKEN
115+
npm ci
116+
npx gulp lint
117+
npx gulp
118+
119+
- name: Generate Local Documentation
120+
working-directory: docs
121+
run: |
122+
GH_TOKEN="${{ secrets.GITHUB_TOKEN }}"
123+
export GH_TOKEN
124+
set -x
125+
npm ci
126+
npx antora antora-playbook.yml --attribute branchesarray=HEAD --stacktrace --log-level=debug
127+
mkdir -p ../build/docs-local
128+
cp -vr build/site/* ../build/docs-local
129+
130+
- name: Upload Website as Artifact
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: Website ${{ runner.os }}
134+
path: build/website
135+
retention-days: 30

.github/workflows/ci-matrix.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ jobs:
115115
116116
submatrices: |
117117
releases: {{ieq is-release-build 'true'}}
118+
# `coverage` is a raw boolean factor (undefined on non-Coverage rows),
119+
# so `ieq` would crash. Wrap in `#if` like the `is-bottleneck` extra-value
120+
# above to handle undefined cleanly.
121+
coverage: {{#if coverage}}true{{/if}}
122+
releases-and-coverage: {{#if (or (ieq is-release-build 'true') coverage)}}true{{/if}}
118123
trace-commands: true
119124
github-token: ${{ secrets.GITHUB_TOKEN }}
120125

.github/workflows/ci-publish.yml

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#
2+
# Licensed under the Apache License v2.0 with LLVM Exceptions.
3+
# See https://llvm.org/LICENSE.txt for license information.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#
6+
# Copyright (c) 2026 Alan de Freitas (alandefreitas@gmail.com)
7+
#
8+
# Official repository: https://github.com/cppalliance/mrdocs
9+
#
10+
# Single-runner publishing step that runs only on push events to
11+
# develop, master, or tags. Renders the full multi-ref Antora site,
12+
# publishes the website to GitHub Pages and the dev-websites rsync
13+
# target, and creates one consolidated GitHub Release containing the
14+
# packages from all three platforms.
15+
16+
name: Publish
17+
18+
on:
19+
workflow_call:
20+
inputs:
21+
submatrix:
22+
description: 'JSON-encoded releases submatrix from cpp-matrix (for platform names)'
23+
type: string
24+
required: true
25+
26+
jobs:
27+
publish:
28+
name: Publish
29+
runs-on: ubuntu-24.04
30+
permissions:
31+
contents: write
32+
steps:
33+
- name: Install packages
34+
uses: alandefreitas/cpp-actions/package-install@v1.9.4
35+
with:
36+
apt-get: rsync git
37+
38+
- name: Clone MrDocs
39+
uses: actions/checkout@v4
40+
with:
41+
fetch-depth: 0
42+
fetch-tags: true
43+
44+
- name: Install Node.js
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: '20'
48+
49+
- name: Download all platform packages
50+
uses: actions/download-artifact@v4
51+
with:
52+
pattern: release-packages-*
53+
path: packages
54+
merge-multiple: true
55+
56+
- name: Download website (Linux)
57+
uses: actions/download-artifact@v4
58+
with:
59+
name: Website Linux
60+
path: build/website
61+
62+
- name: Download demos (Linux)
63+
uses: actions/download-artifact@v4
64+
with:
65+
name: demos${{ (contains(fromJSON('["master", "develop"]'), github.ref_name) && format('-{0}', github.ref_name)) || '' }}-Linux
66+
path: .
67+
68+
- name: Unpack demos
69+
run: |
70+
set -euo pipefail
71+
mkdir -p demos
72+
# generate-demos.sh writes a bzip2 archive despite the .gz suffix;
73+
# -xaf auto-detects compression so we don't have to depend on the
74+
# script keeping the same algorithm.
75+
tar -xaf demos.tar.gz -C demos
76+
77+
- name: Ensure all refs for Antora
78+
run: |
79+
set -euo pipefail
80+
# Make sure Antora sees every branch and tag from the upstream repo,
81+
# regardless of who triggered the workflow.
82+
git remote set-url origin https://github.com/cppalliance/mrdocs.git
83+
git fetch --prune --prune-tags origin \
84+
'+refs/heads/*:refs/remotes/origin/*' \
85+
'+refs/tags/*:refs/tags/*'
86+
87+
# Antora's playbook references `./ui/build/ui-bundle.zip` (relative to
88+
# docs/), so we need the gulp-built bundle in this runner. We could pass
89+
# it as an artifact from Documentation/Linux, but rebuilding here is
90+
# cheap and keeps Publish self-contained.
91+
- name: Generate Antora UI
92+
working-directory: docs/ui
93+
env:
94+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95+
run: |
96+
npm ci
97+
npx gulp
98+
99+
- name: Generate Remote Documentation
100+
working-directory: docs
101+
run: |
102+
GH_TOKEN="${{ secrets.GITHUB_TOKEN }}"
103+
export GH_TOKEN
104+
set -x
105+
npm ci
106+
npx antora --clean --fetch antora-playbook.yml --log-level=debug
107+
mkdir -p ../build/website/docs
108+
cp -vr build/site/* ../build/website/docs
109+
110+
- name: Download previous demos (tags only)
111+
if: startsWith(github.ref, 'refs/tags/')
112+
id: download-prev-demos
113+
uses: actions/download-artifact@v4
114+
continue-on-error: true
115+
with:
116+
name: demos-develop-Linux
117+
path: demos-previous
118+
119+
- name: Compare demos (tags only)
120+
if: startsWith(github.ref, 'refs/tags/') && steps.download-prev-demos.outputs.cache-hit == 'true'
121+
id: compare-demos
122+
run: .github/scripts/compare-demos.sh
123+
124+
- name: Upload demo diff (tags only)
125+
if: startsWith(github.ref, 'refs/tags/') && steps.compare-demos.outputs.diff == 'true'
126+
uses: actions/upload-artifact@v4
127+
with:
128+
name: demos-diff
129+
path: demos-diff
130+
retention-days: 30
131+
132+
- name: Publish website to GitHub Pages
133+
uses: peaceiris/actions-gh-pages@v3
134+
with:
135+
github_token: ${{ secrets.GITHUB_TOKEN }}
136+
publish_dir: build/website
137+
force_orphan: true
138+
139+
- name: Publish website to dev-websites
140+
env:
141+
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
142+
run: |
143+
set -euvx
144+
mkdir -p /home/runner/.ssh
145+
ssh-keyscan dev-websites.cpp.al >> /home/runner/.ssh/known_hosts
146+
chmod 600 /home/runner/.ssh/known_hosts
147+
echo "${{ secrets.DEV_WEBSITES_SSH_KEY }}" > /home/runner/.ssh/github_actions
148+
chmod 600 /home/runner/.ssh/github_actions
149+
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
150+
ssh-add /home/runner/.ssh/github_actions
151+
152+
rsyncopts=(--recursive --delete --links --times --chmod=D0755,F0755 --compress --compress-choice=zstd --rsh="ssh -o StrictHostKeyChecking=no" --human-readable)
153+
website_dir="ubuntu@dev-websites.cpp.al:/var/www/mrdox.com"
154+
demo_dir="$website_dir/demos/${{ github.ref_name }}"
155+
156+
time rsync "${rsyncopts[@]}" --exclude=demos/ --exclude=roadmap/ $(pwd)/build/website/ "$website_dir"/
157+
time rsync "${rsyncopts[@]}" $(pwd)/demos/ "$demo_dir"/
158+
159+
- name: Create changelog
160+
uses: alandefreitas/cpp-actions/create-changelog@v1.9.4
161+
with:
162+
output-path: CHANGELOG.md
163+
thank-non-regular: ${{ startsWith(github.ref, 'refs/tags/') }}
164+
github-token: ${{ secrets.GITHUB_TOKEN }}
165+
limit: 150
166+
update-summary: true
167+
168+
# For non-tag publishes (develop-release and master-release rolling
169+
# releases), strip the project version out of the package filenames
170+
# and insert the branch name instead. Subsequent pushes overwrite the
171+
# existing GitHub-release assets cleanly. Tag releases keep their
172+
# versioned filenames.
173+
- name: Rebrand branch packages
174+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
175+
run: |
176+
set -euxo pipefail
177+
cd packages
178+
for f in MrDocs-*.*.*-*.*; do
179+
[ -e "$f" ] || continue
180+
new=$(echo "$f" | sed -E 's|^MrDocs-[0-9]+\.[0-9]+\.[0-9]+-|MrDocs-${{ github.ref_name }}-|')
181+
mv -- "$f" "$new"
182+
done
183+
184+
- name: Create consolidated GitHub Release
185+
uses: softprops/action-gh-release@v2
186+
with:
187+
files: packages/MrDocs-*-*.*
188+
fail_on_unmatched_files: true
189+
name: ${{ github.ref_name || github.ref }}
190+
tag_name: ${{ github.ref_name || github.ref }}${{ ((!startsWith(github.ref, 'refs/tags/')) && '-release') || '' }}
191+
body_path: CHANGELOG.md
192+
prerelease: false
193+
draft: false
194+
token: ${{ github.token }}

0 commit comments

Comments
 (0)