Skip to content

Commit 75942a6

Browse files
committed
Merge remote-tracking branch 'upstream/main' into codex/fix-asio-println
2 parents 9f4c664 + 82cdb6d commit 75942a6

25 files changed

Lines changed: 3694 additions & 101 deletions

.github/workflows/deploy-site.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ on:
1010
paths:
1111
- 'pkgs/**'
1212
- '.xpkgindex.json'
13+
# The plugin decides how every package reads, the docs are rendered as
14+
# site pages, and the cache is what an offline build renders from — a
15+
# change to any of them changes the site as much as a descriptor does.
16+
- '.xpkgindex/**'
17+
- 'docs/**'
1318
- '.github/workflows/deploy-site.yml'
1419
workflow_dispatch:
1520

@@ -30,13 +35,23 @@ jobs:
3035
runs-on: ubuntu-latest
3136
steps:
3237
- uses: actions/checkout@v4
38+
with:
39+
# The growth curve, the history line and the contributor list are
40+
# replayed from the git log. xpkgindex detects a shallow clone and
41+
# skips all three with a warning, so the default depth of 1 was
42+
# quietly shipping a site with no curve at all.
43+
fetch-depth: 0
3344
- uses: actions/setup-python@v5
3445
with:
3546
python-version: '3.12'
3647
- name: Install xpkgindex
3748
run: pip install git+https://github.com/openxlings/xpkgindex.git
3849
- name: Generate static site
3950
env:
51+
# Raises the API rate limit and enables the author -> login mapping
52+
# that merges one person's several git identities. The build works
53+
# without it, with fewer avatars and less merging.
54+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4055
# xpkgindex >= Apr 2026 surfaces these on the About page.
4156
XPKGINDEX_BUILD_TIME: ${{ github.event.head_commit.timestamp }}
4257
XPKGINDEX_BUILD_COMMIT: ${{ github.sha }}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: refresh-site-cache
2+
3+
# Manual refresh of the data the site cannot read from `pkgs/` alone:
4+
# upstream repo metadata (stars, avatars, contributor logins) and, for Form A
5+
# packages, the upstream `mcpp.toml` that actually holds their build
6+
# information.
7+
#
8+
# Deliberately manual. The normal `deploy-site` build reads the committed
9+
# cache and touches no network, so a rendered page never depends on GitHub
10+
# being reachable at deploy time; this job is how new data gets in.
11+
#
12+
# Run it after adding a package or bumping one to a new upstream tag — the
13+
# cache is keyed by URL and a manifest URL contains the release tag, so a
14+
# bumped package fetches fresh while everything else is reused.
15+
16+
on:
17+
workflow_dispatch:
18+
inputs:
19+
reason:
20+
description: "Why (shows up in the commit message)"
21+
required: false
22+
default: "manual refresh"
23+
24+
permissions:
25+
contents: write
26+
27+
jobs:
28+
refresh:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v4
32+
with:
33+
fetch-depth: 0 # same reason as deploy-site: history replay
34+
- uses: actions/setup-python@v5
35+
with:
36+
python-version: '3.12'
37+
38+
- name: Install xpkgindex
39+
run: pip install git+https://github.com/openxlings/xpkgindex.git
40+
41+
- name: Refresh cache
42+
env:
43+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
run: xpkgindex generate . --output /tmp/site --refresh
45+
46+
- name: Commit if anything changed
47+
run: |
48+
if git diff --quiet -- .xpkgindex/cache; then
49+
echo "cache unchanged"
50+
exit 0
51+
fi
52+
git config user.name "github-actions[bot]"
53+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
54+
git add .xpkgindex/cache
55+
git commit -m "chore(site): refresh upstream cache (${{ inputs.reason }})"
56+
git push

.github/workflows/site-check.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: site-check
2+
3+
# Builds the site on a pull request without publishing it. `validate.yml`
4+
# proves the packages compile; this proves they still render — a descriptor
5+
# that parses fine can still collide with another package's URL, and the
6+
# plugin reads fields no compiler checks.
7+
#
8+
# Deliberately offline: a pull request should not spend the API rate limit,
9+
# and the result should depend only on what is in the repository.
10+
11+
on:
12+
pull_request:
13+
paths:
14+
- 'pkgs/**'
15+
- '.xpkgindex.json'
16+
- '.xpkgindex/**'
17+
- 'docs/**'
18+
- '.github/workflows/site-check.yml'
19+
workflow_dispatch:
20+
21+
jobs:
22+
build:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0 # --strict checks the replayed history against the tree
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: '3.12'
31+
32+
- name: Install xpkgindex
33+
run: pip install git+https://github.com/openxlings/xpkgindex.git
34+
35+
- name: Build the site
36+
# --strict turns the growth reconciliation warning into an error: if
37+
# the replayed history disagrees with the tree, the curve on the site
38+
# would be wrong, and that is worth failing a pull request over.
39+
run: xpkgindex generate . --output /tmp/site --offline --strict | tee /tmp/build.log
40+
41+
- name: No warnings
42+
# A duplicate slug or an unparsable descriptor already fails above.
43+
# Everything else the build is unhappy about arrives as a warning, and
44+
# a warning nobody reads is a warning that becomes permanent.
45+
run: |
46+
if grep -q 'warning:' /tmp/build.log; then
47+
echo "::error::the site build reported warnings"
48+
grep 'warning:' /tmp/build.log
49+
exit 1
50+
fi
51+
52+
- name: The pages a reader lands on exist
53+
run: |
54+
set -e
55+
for f in index.html index.json stats/index.html contributors/index.html \
56+
about/index.html docs/quick-start/index.html \
57+
zh/index.html zh-Hant/index.html; do
58+
test -s "/tmp/site/$f" || { echo "::error::missing $f"; exit 1; }
59+
done
60+
61+
- uses: actions/upload-artifact@v4
62+
if: always()
63+
with:
64+
name: site
65+
path: /tmp/site
66+
retention-days: 7

.github/workflows/validate.yml

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,65 @@ jobs:
404404
"$1" "$2" "$3" "$4" "$5" "$6" "$i" "$7"
405405
done
406406
}
407-
if [ "$full" = 1 ]; then ln=3; mn=1; wn=2; else ln=1; mn=1; wn=1; fi
407+
# Shard count follows the WORK, per platform, measured.
408+
#
409+
# It used to be binary — full run: linux 3 / macos 1 / windows 2,
410+
# anything else: 1 each — which asserts two things that are not
411+
# true. "A partial run is small": touching a widely consumed
412+
# descriptor selects every member that consumes it, and this PR's
413+
# `pkgs/c/compat.openssl.lua` selected four; one linux shard took
414+
# grpc-codegen (3563s) and grpc-module (1701s) back to back and was
415+
# cancelled at exactly 1h30m, the job cap. "A full macOS run fits in
416+
# one shard": at 6922s measured it does not — it fit only while the
417+
# total sat just under the cap, and the run that added grpc-codegen
418+
# (1715s on macOS) pushed it to 1h30m20s.
419+
#
420+
# Sharding is not only a wall-clock lever. Each shard is its own job
421+
# with its own `timeout-minutes`, so it is also how the work is made
422+
# to FIT. That is the half the "macOS concurrency is 1, so extra
423+
# shards run back to back" note above left out: back to back is fine
424+
# when the alternative is not finishing.
425+
#
426+
# tests/member-timings.tsv already holds every member's measured
427+
# cost and plan_shards.lua already packs by it (LPT), so the fan-out
428+
# comes from the same table: sum this run's members for that
429+
# platform and take one shard per ~70 minutes, which leaves ~20
430+
# minutes of headroom under the 90-minute cap for a cold cache.
431+
#
432+
# The caps are where runner concurrency comes back in: linux 3 (the
433+
# measured concurrency — a 4th shard would queue), macOS 2, windows
434+
# 2. Past those, more shards buy fit that is already there and pay
435+
# another checkout + mcpp download + cache restore.
436+
#
437+
# Full run, from the table: linux 13570s over 3 -> ~75min/shard
438+
# (observed slowest 77), macOS 6922s over 2 -> ~57, windows 8043s
439+
# over 2 -> ~67. linux is the tight one — its cap binds before the
440+
# ~70-minute target does, so it is the first place to look if a
441+
# cold full run starts brushing 90 again. The levers, in order:
442+
# raise the linux cap to 4 (costs a queued runner), then the job
443+
# timeout.
444+
shards_for() { # platform cap -> shard count
445+
local secs
446+
secs=$(XPLAT="$1" lua5.4 -e '
447+
local plat = os.getenv("XPLAT")
448+
local sel, all = {}, (os.getenv("MEMBERS") == "__ALL__")
449+
if not all then
450+
for m in (os.getenv("MEMBERS") or ""):gmatch("%S+") do sel[m] = true end
451+
end
452+
local total = 0
453+
for line in io.lines("tests/member-timings.tsv") do
454+
local p, m, s = line:match("^(%S+)\t(%S+)\t(%d+)$")
455+
if p == plat and m and (all or sel[m]) then total = total + tonumber(s) end
456+
end
457+
print(total)')
458+
local n=$(( secs / 4200 + 1 ))
459+
[ "$n" -gt "$2" ] && n="$2"
460+
echo "$1 work: ${secs}s (measured) -> $n shard(s)" >&2
461+
echo "$n"
462+
}
463+
ln=$(shards_for linux 3)
464+
mn=$(shards_for macos 2)
465+
wn=$(shards_for windows 2)
408466
{
409467
printf '{"include":['
410468
emit linux ubuntu-latest linux-x86_64 tar.gz bin/mcpp registry/bin/xlings "$ln"

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ tests/examples/*/imgui.ini
1111

1212
# 本地 git worktree(逐包验证时开的),不属于索引内容
1313
.worktrees/
14+
15+
# plugin bytecode
16+
.xpkgindex/plugins/__pycache__/

0 commit comments

Comments
 (0)