Skip to content

Commit 1b2a296

Browse files
sunnamed434claude
andcommitted
docs(workflows): trim verbose comments for readability
Condense the multi-line explanatory comment blocks across the redist workflows to concise one/two-liners; deeper rationale already lives in ARCHITECTURE.md. Comment-only (verified: no non-comment lines changed), ~80 fewer comment lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 47f3c09 commit 1b2a296

4 files changed

Lines changed: 62 additions & 142 deletions

File tree

.github/workflows/redist-cleanup.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ jobs:
2323
echo "Locking PR #${{ github.event.pull_request.number }}"
2424
gh pr lock "${{ github.event.pull_request.number }}" --repo "${{ github.repository }}" --reason resolved || true
2525
26-
# Only delete after a successful merge. Never delete the branch of a PR
27-
# that was closed without merging (it may contain work to investigate).
28-
# PRs closed-as-unnecessary by create-pull-request are already cleaned up
29-
# by its delete-branch:true, so this is the merge case.
26+
# Only delete the branch after a successful merge (never for a closed-unmerged PR).
3027
- name: Delete merged PR branch
3128
if: github.event.pull_request.merged == true
3229
env:

.github/workflows/redist-publish.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,8 @@ jobs:
7575
# load-variants already filtered the matrix to the requested variant(s).
7676
should_run=true
7777
else
78-
# Native git diff replaces tj-actions/changed-files (one less third-party
79-
# action). The Update pipeline squash-merges one variant per commit, so
80-
# github.event.before is the prior master tip; fall back to HEAD~1.
78+
# Native git diff (no tj-actions/changed-files). github.event.before is the
79+
# prior master tip; fall back to HEAD~1.
8180
before="$BEFORE_SHA"
8281
if [ -z "$before" ] || [ "$before" = "0000000000000000000000000000000000000000" ]; then
8382
before="HEAD~1"

.github/workflows/redist-update.yaml

Lines changed: 46 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,9 @@ concurrency:
2121
cancel-in-progress: false
2222

2323
jobs:
24-
# Single source of truth: the variant matrix lives in .github/variants.json.
25-
# This job emits TWO matrices from it:
26-
# - sources: one entry per distinct Steam (appId, branch) "source". The
27-
# game is downloaded ONCE per source (see download_sources).
28-
# - variants: the flat per-variant list (see update_variant), each of which
29-
# reuses its source's single download.
30-
# To add/remove a variant, edit .github/variants.json only.
24+
# Emits two matrices from .github/variants.json (the single source of truth):
25+
# `sources` (one per Steam appId+branch, downloaded once) and `variants` (flat
26+
# per-variant list). Add/remove variants by editing variants.json.
3127
load:
3228
name: "Load matrices"
3329
runs-on: ubuntu-latest
@@ -43,9 +39,7 @@ jobs:
4339
env:
4440
INPUT_VARIANT: ${{ github.event.inputs.variant }}
4541
EVENT_NAME: ${{ github.event_name }}
46-
# Opt-in: set this repo variable to 'true' once a SECOND Steam account
47-
# (STEAM_USERNAME_2 / STEAM_PASSWORD_2) exists. Until then the two client
48-
# sources stay on one account, serialized — exactly as before.
42+
# Opt-in 2nd Steam account (see ARCHITECTURE.md); empty/false = unchanged.
4943
STEAM_SECOND_ACCOUNT_ENABLED: ${{ vars.STEAM_SECOND_ACCOUNT_ENABLED }}
5044
run: |
5145
set -euo pipefail
@@ -60,22 +54,10 @@ jobs:
6054
base=$(jq -c '.' .github/variants.json)
6155
fi
6256
63-
# Group the (possibly filtered) variants by their Steam source. The
64-
# source label "<appId>-<branch|default>" is reused as the artifact
65-
# name that ties download_sources -> update_variant together.
66-
#
67-
# Per source we also derive (here, where vars + jq are easy, so
68-
# download_sources stays dumb):
69-
# steamAccount credential set to log in with: 0=anonymous, 1=primary
70-
# (STEAM_USERNAME). The authenticated PREVIEW client source
71-
# becomes 2 (STEAM_USERNAME_2) ONLY when a second account is
72-
# enabled, so it logs into a DIFFERENT account than the
73-
# default client source and the two can run concurrently.
74-
# dlgroup download concurrency group. Anonymous sources — and, when
75-
# the 2nd account is on, every source — get a unique group
76-
# (parallel). Otherwise the two client sources share
77-
# "authenticated" (serialized): concurrent logins to ONE
78-
# account fail with AlreadyLoggedInElsewhere.
57+
# Group variants by Steam source (appId+branch); the source label doubles as
58+
# the artifact name linking download_sources -> update_variant. Also derive per
59+
# source: steamAccount (0=anon, 1=primary, 2=2nd account for the preview client)
60+
# and dlgroup (download concurrency group). See ARCHITECTURE.md.
7961
second="${STEAM_SECOND_ACCOUNT_ENABLED:-false}"
8062
sources=$(printf '%s' "$base" | jq -c --arg second "$second" '
8163
group_by(.appId + "|" + .branch)
@@ -101,11 +83,9 @@ jobs:
10183
echo "Sources to probe:"
10284
printf '%s' "$sources" | jq -r '.[] | " \(.source) (variants: \(.variants))"'
10385
104-
# One job per distinct Steam (appId, branch) source. Probe the manifest once;
105-
# if it changed, download the game ONCE and publish just the bits the redist
106-
# tool needs (Managed DLLs + appmanifest + Status.json) as an artifact that
107-
# every variant of this source reuses. This is where the only Steam logins
108-
# happen, so it's the only place that needs serializing.
86+
# One job per Steam source: probe the manifest once; if changed, download the game
87+
# once and upload the bits the tool needs (Managed DLLs + appmanifest + Status.json)
88+
# as an artifact every variant of this source reuses. The only Steam logins happen here.
10989
download_sources:
11090
name: "Download ${{ matrix.source }}"
11191
runs-on: ubuntu-latest
@@ -114,15 +94,9 @@ jobs:
11494
fail-fast: false
11595
matrix:
11696
include: ${{ fromJson(needs.load.outputs.sources) }}
117-
# The download concurrency group is precomputed per source by the load job
118-
# (matrix.dlgroup). Anonymous (server) sources always get a unique group → run
119-
# in parallel. By default the two authenticated (client) sources share ONE Steam
120-
# account, so they share the "authenticated" group → serialized (concurrent
121-
# logins to one account fail with AlreadyLoggedInElsewhere). With only two
122-
# members a concurrency group keeps 1 running + 1 pending and never cancels (the
123-
# 3+ case GitHub does cancel cannot occur). When a 2nd Steam account is enabled
124-
# (vars.STEAM_SECOND_ACCOUNT_ENABLED == 'true') the preview client source logs
125-
# into account 2 and gets its own group → the two client downloads run parallel.
97+
# Per-source download group (matrix.dlgroup): server sources run parallel; the two
98+
# client sources share one account so they're serialized, unless a 2nd account is
99+
# enabled (then each gets its own group). See ARCHITECTURE.md.
126100
concurrency:
127101
group: redist-dl-${{ matrix.dlgroup }}
128102
cancel-in-progress: false
@@ -165,9 +139,7 @@ jobs:
165139
beta_args=(-beta "$APP_BRANCH_NAME")
166140
fi
167141
168-
# steamAccount picks the credential set: 2 = the optional second account
169-
# (STEAM_USERNAME_2), used by the preview client source so it logs into a
170-
# DIFFERENT account than the default client source; otherwise the primary.
142+
# account 2 = optional 2nd Steam account (preview client); see ARCHITECTURE.md.
171143
if [ "$STEAM_ACCOUNT" = "2" ]; then
172144
STEAM_USERNAME="$STEAM_USERNAME_2"
173145
STEAM_PASSWORD="$STEAM_PASSWORD_2"
@@ -185,12 +157,9 @@ jobs:
185157
auth_args+=(-username "$STEAM_USERNAME" -password "$STEAM_PASSWORD")
186158
fi
187159
188-
# DepotDownloader can drop its Steam connection mid-probe ("Lost
189-
# connection to Steam" / "A task was canceled") and exit WITHOUT a
190-
# "Manifest <id>" line — a known transient (SteamRE/DepotDownloader
191-
# #223, #691, incl. the pinned 3.4.0), not a real auth/format failure.
192-
# Mirror the steamcmd retry in "Download game files": retry the fetch and
193-
# gate on a valid id; only fail loudly once all attempts are exhausted.
160+
# DepotDownloader can drop its connection mid-probe and emit no "Manifest <id>"
161+
# line — a known transient (SteamRE/DepotDownloader #223, #691). Retry, gate on
162+
# a valid id, fail loud only when exhausted.
194163
current_manifest=""
195164
manifest_output=""
196165
attempts=4
@@ -205,9 +174,7 @@ jobs:
205174
"${beta_args[@]}" \
206175
-dir redist/temp_depots || true)
207176
208-
# Prints e.g. "Manifest 763708736677468005 (date)". Manifest ids are
209-
# 64-bit, so their length varies (~17-20 digits) — grab the number
210-
# after the "Manifest" keyword rather than assuming a fixed width.
177+
# Grab the number after "Manifest" (64-bit id, ~17-20 digits, variable width).
211178
current_manifest=$(printf '%s\n' "$manifest_output" | grep -oiE 'manifest[[:space:]]+[0-9]+' | grep -oE '[0-9]+' | head -n 1 || true)
212179
if [[ "$current_manifest" =~ ^[0-9]{10,20}$ ]]; then
213180
break
@@ -224,9 +191,7 @@ jobs:
224191
echo "Current manifest: $current_manifest"
225192
echo "current_manifest=$current_manifest" >> "$GITHUB_OUTPUT"
226193
227-
# This source needs a download if ANY of its variants' recorded
228-
# manifest ids differs from the live one (or is missing). They normally
229-
# all match; "any differs" lets a lagging variant catch up.
194+
# Download if ANY variant's recorded manifest id differs from the live one.
230195
changed=false
231196
IFS=',' read -ra source_variants <<< "$VARIANTS"
232197
for v in "${source_variants[@]}"; do
@@ -276,11 +241,8 @@ jobs:
276241
if [ -n "$APP_BRANCH_NAME" ]; then
277242
beta_args=(-beta "$APP_BRANCH_NAME")
278243
fi
279-
# steamcmd is flaky: it can exit non-zero on success and fail downloads
280-
# transiently. Its exit code isn't reliable, so we RETRY and gate on the
281-
# real artifact — steamcmd only writes appmanifest_<appid>.acf once the
282-
# update completes (the same "no appmanifest -> force update" remedy
283-
# LinuxGSM uses). The redist tool needs that file downstream.
244+
# steamcmd's exit code is unreliable, so retry and gate on the real artifact:
245+
# appmanifest_<appid>.acf, written only on a completed update and needed by the tool.
284246
manifest_present() {
285247
find "$GITHUB_WORKSPACE" -name "appmanifest_${APP_ID}.acf" -print -quit 2>/dev/null | grep -q .
286248
}
@@ -304,9 +266,8 @@ jobs:
304266
if: steps.probe.outputs.source_changed == 'true'
305267
run: echo "${{ steps.probe.outputs.current_manifest }}" > source-manifest.txt
306268

307-
# Publish only the small bits the redist tool reads — NOT the multi-GB game.
308-
# The artifact's presence is also the "this source changed" signal that
309-
# update_variant keys off (a missing artifact => unchanged => skip).
269+
# Upload only the small bits the tool reads (not the multi-GB game). The
270+
# artifact's presence is also the "source changed" signal update_variant keys off.
310271
- name: Upload source files
311272
if: steps.probe.outputs.source_changed == 'true'
312273
uses: actions/upload-artifact@v7
@@ -321,25 +282,20 @@ jobs:
321282
if-no-files-found: warn
322283
retention-days: 1
323284

324-
# One job per variant, FULLY PARALLEL: these never touch Steam — each pulls its
325-
# source's artifact (the single download above), runs the redist tool, and opens
326-
# its rolling PR. No Steam login here means no account contention, so there is
327-
# nothing to serialize.
285+
# One job per variant, fully parallel: pull the source artifact, run the tool, open
286+
# the rolling PR. No Steam login here, so nothing to serialize.
328287
update_variant:
329288
name: "Update ${{ matrix.variant }}"
330289
runs-on: ubuntu-latest
331290
needs: [load, download_sources]
332-
# Job-level permissions REPLACE the workflow defaults, so this must list
333-
# everything GITHUB_TOKEN needs here: contents (checkout), and actions:read
334-
# for the "list this run's artifacts" gate. (The PR itself is created with
335-
# secrets.PAT, independent of these.)
291+
# Job-level permissions REPLACE workflow defaults: contents (checkout) + actions:read
292+
# (the artifacts gate). The PR is created with secrets.PAT, independent of these.
336293
permissions:
337294
contents: write
338295
pull-requests: write
339296
actions: read
340-
# Run even if some source download failed (those variants just find no
341-
# artifact and skip); notify-failure still flags the failed source. Skip only
342-
# if the load job itself failed (then there's no matrix to run).
297+
# Run even if a source download failed (those variants find no artifact and skip);
298+
# only skip if load itself failed.
343299
if: ${{ !cancelled() && needs.load.result == 'success' }}
344300
strategy:
345301
fail-fast: false
@@ -372,12 +328,8 @@ jobs:
372328
SOURCE_KEY: ${{ steps.ids.outputs.source_key }}
373329
run: |
374330
set -euo pipefail
375-
# Fail LOUD on an API error. The ONLY thing that may mean "this source
376-
# is unchanged" is a SUCCESSFUL artifacts listing that doesn't contain
377-
# our artifact. If the gh call itself fails (transient 5xx / network /
378-
# rate-limit), we must NOT treat that as "unchanged" — that would
379-
# silently skip a genuinely-changed source under a green run, and
380-
# notify-failure (failure()-only) would never fire. Retry, then fail.
331+
# Fail LOUD on API error: only a SUCCESSFUL listing without our artifact means
332+
# "unchanged". A failed gh call must NOT be read as unchanged. Retry, then fail.
381333
ok=false
382334
names=""
383335
for attempt in 1 2 3; do
@@ -469,9 +421,8 @@ jobs:
469421
fi
470422
printf '%s\n' "$tool_output"
471423
472-
# Record the manifest id this build was produced from so the next probe
473-
# sees "no change". Lives outside REDIST_DIR so the discard step below never
474-
# reverts it, even when no package is published.
424+
# Record the manifest id so the next probe sees "no change". Outside REDIST_DIR so
425+
# the discard step never reverts it.
475426
- name: Record source manifest id
476427
if: steps.gate.outputs.changed == 'true'
477428
env:
@@ -498,14 +449,9 @@ jobs:
498449
echo "COMMIT_EOF"
499450
} >> "$GITHUB_OUTPUT"
500451
else
501-
# No .commit means the tool did NOT bump the version: the Steam build /
502-
# depot manifest changed, but the game version (X.Y.Z.N) did not. We
503-
# cannot republish the same NuGet version, so the regenerated DLLs are
504-
# unpublishable (would 409). Discard them in the variant dir and keep
505-
# ONLY the corrected Steam manifest id (recorded above) so this build is
506-
# logged and not re-processed every run. The real DLLs publish on the
507-
# next game-version bump. (A tool failure already failed the step above,
508-
# so a missing .commit here is a legitimate no-op, not a silent error.)
452+
# No .commit => version unchanged (Steam build moved but game version didn't).
453+
# Can't republish the same NuGet version, so discard the regenerated DLLs and
454+
# keep only the recorded manifest id; the DLLs publish on the next version bump.
509455
git checkout -- "$REDIST_DIR" 2>/dev/null || true
510456
echo "message=Record ${{ matrix.variant }} Steam manifest (game version unchanged; no package update)" >> "$GITHUB_OUTPUT"
511457
fi
@@ -522,9 +468,8 @@ jobs:
522468
echo "has_git_changes=true" >> "$GITHUB_OUTPUT"
523469
fi
524470
525-
# peter-evans/create-pull-request commits to a fixed-name branch and keeps
526-
# the open PR continually updated until it is merged/closed; delete-branch
527-
# cleans it up afterwards. No timestamped branches or existing-PR lookups.
471+
# Commits to a fixed-name branch and keeps the rolling PR updated until merged;
472+
# delete-branch cleans up afterwards.
528473
- name: Create Pull Request
529474
if: steps.gate.outputs.changed == 'true' && steps.check_git_changes.outputs.has_git_changes == 'true'
530475
id: create_pr
@@ -581,9 +526,8 @@ jobs:
581526
fi
582527
} >> "$GITHUB_STEP_SUMMARY"
583528
584-
# Make silent breakage visible: if any scheduled source download or variant
585-
# update fails, open (or comment on) a tracking issue instead of relying on
586-
# someone watching the Actions tab.
529+
# On any scheduled-run failure, open (or comment on) a tracking issue so breakage
530+
# isn't silent.
587531
notify-failure:
588532
name: "Notify on failure"
589533
needs: [load, download_sources, update_variant]
@@ -602,9 +546,7 @@ jobs:
602546
set -euo pipefail
603547
marker="Redist auto-update workflow failed"
604548
body=$(printf '⚠️ The scheduled redist update workflow failed.\n\nRun: %s\n\nA source download (Steam auth/network, DepotDownloader, steamcmd) or a variant update (the redist tool or PR creation) errored. Check the run for the failing job.' "$RUN_URL")
605-
# --repo is required: this job has no checkout, so gh can't infer the
606-
# repo from a git remote (and gh does NOT read GITHUB_REPOSITORY). Without
607-
# it the label is never created and the gh issue create --label below fails.
549+
# --repo is required here: no checkout, and gh doesn't read GITHUB_REPOSITORY.
608550
gh label create update-failure --repo "$REPO" --color B60205 --description "Automated redist update failure" --force >/dev/null 2>&1 || true
609551
existing=$(gh issue list --repo "$REPO" --state open --search "in:title \"$marker\"" --json number --jq '.[0].number // empty')
610552
if [ -n "$existing" ]; then
@@ -616,14 +558,10 @@ jobs:
616558
workflow-keepalive:
617559
if: github.event_name == 'schedule'
618560
runs-on: ubuntu-latest
619-
# GitHub disables scheduled workflows after 60 days of repo inactivity; this job
620-
# re-enables this workflow on each scheduled run to prevent that. Inlined (was
621-
# liskin/gh-workflow-keepalive) so we don't depend on an external, unmaintained
622-
# action for a one-line gh-api call that runs with actions:write — same approach
623-
# the action used (PUT .../enable), no dummy commits. The default token
624-
# occasionally returns a transient 401 here; keepalive is non-critical and
625-
# self-healing (the next scheduled run re-enables), so continue-on-error keeps a
626-
# blip from reddening an otherwise-green run.
561+
# Re-enable this scheduled workflow (GitHub disables them after 60 days idle).
562+
# Inlined gh-api call, no external dependency. continue-on-error: the default token
563+
# occasionally 401s here; keepalive is non-critical and self-healing, so a blip
564+
# must not redden the run.
627565
continue-on-error: true
628566
permissions:
629567
actions: write

0 commit comments

Comments
 (0)