Skip to content

fix(actions): batch of small correctness fixes across the seven actions #107

Description

@mmcky

A batch of independent, small correctness defects across the actions. None is individually urgent; together they account for most of the "silent wrong behaviour" found in the 2026-07 maintenance audit. Each is a few lines.

setup-environment

Container-mode conda env update omits -n, so a delta env file can update the wrong environmentaction.yml:77. Standard mode passes -n ${{ inputs.environment-name }} at :139; container mode does not, so conda resolves the target from the file's own name: key. A lecture repo whose delta file says name: lecture-python gets /opt/conda/envs/lecture-python, which is not on the container PATH — the step prints "✅ Environment updated successfully" and the build fails much later with ModuleNotFoundError. Fix: conda env update -n "$ENV_NAME" -f "$ENV_UPDATE", move the path into env: rather than interpolating into the shell, and warn if the file's name: differs.

LaTeX install dies with no output on an empty requirements file, and passes trailing comments to aptaction.yml:147. Under -o pipefail a fully-commented file makes the second grep exit 1 and kills the step with zero diagnostics. grep -v '^#' also strips only whole-line comments, so texlive-xetex # for unicode math reaches apt verbatim; $PACKAGES is unquoted at :150. Fix: sed -e 's/#.*//' into a mapfile array, warn-and-skip if empty, install -y "${pkgs[@]}".

The environment summary reports the wrong Python environment in standard modeaction.yml:163 and :201. The step uses plain bash, correct for containers, but setup-miniconda activates via the login profile — which is why :135 uses bash -l {0}. On a standard runner pip list reports the runner's default Python, directly below a confident "Conda: Restored from cache ✅". Fix: branch on container-mode, or invoke "$CONDA/envs/$ENV_NAME/bin/python" -m pip list explicitly, and drop the 2>/dev/null.

build-lectures

The build-failure banner names an artifact that doesn't exist and the wrong reports directoryaction.yml:156, :159, :160. The banner hardcodes execution-reports-{builder} but :172 honours failure-artifact-name, which test-containers-lectures.yml:84 always sets — so every failing container-validation run prints a wrong download instruction. Line 160 also sends pdflatex users to _build/pdflatex/reports/; the real path is _build/latex/reports per the case at :125. Fix: compute both strings once in env: and echo those. PLAN item 15 flags the path half only.

build-jupyter-cache

builders is validated and parsed by substring, so unknown builders are silently droppedaction.yml:89, :103-124. The input is documented as comma-separated but never split. builders: 'html,pdf' passes validation and builds HTML only with no warning; 'nojupyter' enables the jupyter build. The same three tests are repeated three times across two steps. Fix: split on commas once, case each trimmed token against html|pdflatex|jupyter, error on anything else, and emit the three run-* outputs from that loop.

"Fail if builds failed" is implicitly gated on success()action.yml:369. An if: with no status function gets an implicit success() &&, so once the issue-creation step at :285 errors — gh absent in-container, or no issues: write — the only ::error::One or more builds failed annotation is never emitted, and the surfaced cause points at the notification plumbing instead of the build. Fix: if: always() && … plus continue-on-error: true on the issue step.

The failure-notification path aborts on ordinary input and on a missing labelcreate-failure-issue.sh:81, :95-99. ASSIGNEES_FLAG="--assignee $ISSUE_ASSIGNEES" is deliberately unquoted, so 'alice, bob' becomes --assignee alice, plus a stray positional and gh exits non-zero under set -e. And gh issue create --label fails hard when a label does not exist — the default build-failure,automated is not a GitHub default, so the first failure on a fresh repo produces no issue at all. Fix: build assignee args as an array; retry without --label (with a ::warning::) on failure.

The auto-created failure issue gives an unrunnable repro commandcreate-failure-issue.sh:66 suggests jb build $SOURCE_DIR --builder <failed-builder>; for the jupyter builder the real invocation is --builder=custom --custom-builder=jupyter -n per build-lectures/action.yml:104, and --path-output is missing in all cases.

publish-gh-pages

asset-url is bound to an output action-gh-release does not exposeaction.yml:32. softprops/action-gh-release exposes url, id, upload_url, assets — never asset-url — so the output is always empty while README.md:42 advertises it. Fix: delete the output and the README row (PLAN item 7), or repoint at fromJSON(steps.upload-release.outputs.assets)[0].browser_download_url.

scripts/

Renamed lecture files never get a preview deep linkdetect-changed-lectures.sh:37-40. git diff --name-status reports renames as R<score> with two tab-separated paths; the *) continue arm drops them, so a renamed lecture — a routine editorial change — is missing from the preview comment. Fix: pass --no-renames on :29 so renames decompose into A/D pairs.

Checklist

  • conda env update -n
  • Robust LaTeX package parsing
  • Container/standard split for the environment summary
  • Failure-banner artifact name and reports path computed once
  • Exact-match builder parsing in build-jupyter-cache
  • if: always() && on the final fail step
  • Array-based assignees + label fallback in create-failure-issue.sh
  • Real per-builder repro command in the issue body
  • Resolve asset-url
  • --no-renames in detect-changed-lectures.sh

Advances #83 (issue-body/artifact alignment) and PLAN items 14/15.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions