Skip to content

util/: share one stdlib-only GitHub Actions helper instead of re-implementing annotations and outputs per script #2047

Closed

Description

@JarryShaw

Is your feature request related to a problem?
The util/ scripts that #1967 and #2030 moved the workflow shell into each re-implement the same GitHub Actions plumbing. The ::warning/::error annotation writers, $GITHUB_OUTPUT and $GITHUB_STEP_SUMMARY appenders, and subprocess run-and-report wrappers are copied across apt_packages.py, classify_changes.py, discussion_report.py, leg_summary.py, pip_install.py, regenerate_samples.py, superseded.py, vendor_test_gate.py, verdict_covers_checkout.py and others.

Is a third-party tool the answer? I don't think so, for two reasons:

  • pexpect drives interactive programs over a pty. None of these commands is interactive: each runs, exits, and has its output parsed, which subprocess.run already does. pexpect would add a dependency, and its spawn is unavailable on Windows (pexpect docs, "Pexpect on Windows").
  • The CI-path scripts are standard library only on purpose (see the scripts section of workflows.rst). They run on the image's /usr/bin/python3, or on a leg interpreter that may be broken, 3.7, GraalPy or free-threaded, and pip_install.py is the install step. A third-party helper would have to be installed by the step it exists to run.
  • Scripts that run in a controlled environment already use third-party packages where it pays: requests and lxml in ci_timing.py, psutil in vendor_test_gate.py, yaml and markdown_it in update_python_versions.py. That stays as it is.

Needs you:

  • (a) Recommended: add one stdlib-only helper, util/_actions.py, with annotate(), set_output(), summary(), group() and run(). Each script imports it, and a project test pins the helper as standard library only. It is one PR per batch of scripts, with no behaviour change, and each moved script keeps its existing tests.
  • (b) Leave it duplicated. Each script stays self-contained, so it can be copied or run without the others.
  • (c) Adopt a third-party toolkit only for scripts off the install path. That gives two styles side by side.

Activity

  1. added
    ciPull requests that change CI or workflow configuration (ci: subject prefix)
    refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 22, 2026
  2. JarryShaw commented on Oct 22, 2026

    @JarryShaw
    OwnerAuthor

    take (a)

  3. JarryShaw commented on Oct 22, 2026

    @JarryShaw
    OwnerAuthor

    Recorded: (a). The plan:

    • First PR: add util/_actions.py, standard library only, providing annotate(), set_output(), summary(), group() and run(). A project test pins it to the standard library and to each script's existing output format. The first batch of scripts moves onto it.
    • Later PRs: one per remaining batch, each with no behaviour change.

    The scripts behind open PRs (#2039, and the #2044 worker) wait until those land. A worker is on the first PR now.

  4. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 22, 2026
  5. JarryShaw commented on Oct 23, 2026

    @JarryShaw
    OwnerAuthor

    Done. With #2079 merged, every util/ script writes its Actions output through util/_actions.py. A scan of origin/main finds no script that emits ::warning/::error/::notice/::group by hand without the helper. The batches were #2063, #2069 and #2079. test_actions_helper_2047 pins the full list and the stdlib-only imports.

  6. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ciPull requests that change CI or workflow configuration (ci: subject prefix)refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions