chore: use standalone action repositories#639
Conversation
9e10286 to
01ec4a1
Compare
|
7 fixed, 2 new since branch point (4ed92fc) ❌ 2 new CodeQL alerts since the previous PR commit
✅ 7 CodeQL alerts resolved since the previous PR commit
❌ 2 new CodeQL alerts since the branch point
✅ 7 CodeQL alerts resolved since the branch point
Review the full CodeQL report for details. |
There was a problem hiding this comment.
Pull request overview
This PR aims to complete the migration away from in-repo composite actions by removing .github/actions/* and adding operator documentation for exporting those actions into standalone Framework-R-D/action-* repositories, alongside related devcontainer and tooling updates.
Changes:
- Add a self-contained operator guide (
docs/dev/export-actions-plan.md) and a long-form planning prompt under.github/prompts/. - Update
scripts/git-ai-committo improve token handling for Copilot fallback, clean model output, and add prompt-size-based model escalation. - Refresh pre-commit hook revisions and adjust devcontainer host/container wiring for Kilo + headroom/proxy support.
Reviewed changes
Copilot reviewed 51 out of 51 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/test/test_git_ai_commit.py |
Adds tests for new git-ai-commit helpers and staged-diff handling behavior. |
scripts/test/test_check_codeql_alerts.py |
Simplifies zip() usage in a test loop. |
scripts/git-ai-commit |
Adds OAuth-token resolution helper, response cleaning, prompt escalation logic, and refactors confirmation I/O. |
docs/dev/export-actions-plan.md |
New operator guide describing end-to-end export workflow for actions into standalone repos. |
AGENTS.md |
Adds a note related to tool usage parameters. |
.pre-commit-config.yaml |
Bumps hook revisions and switches to gersemi-pre-commit. |
.github/prompts/plan-exportReusableActions.prompt.md |
Adds a large planning prompt describing the export/migration procedure in detail. |
.github/prompts/.gitignore |
Ignores prompt backup/checkpoint artifacts. |
.github/actions/workflow-setup/action.yaml |
Removes the in-repo workflow-setup composite action definition. |
.github/actions/setup-build-env/action.yaml |
Removes the in-repo setup-build-env composite action definition. |
.github/actions/run-change-detection/action.yaml |
Removes the in-repo run-change-detection composite action definition. |
.github/actions/README.md |
Removes the in-repo composite-actions README. |
.github/actions/prepare-fix-outputs/action.yaml |
Removes the in-repo prepare-fix-outputs composite action definition. |
.github/actions/prepare-check-outputs/action.yaml |
Removes the in-repo prepare-check-outputs composite action definition. |
.github/actions/post-clang-tidy-results/action.yaml |
Removes the in-repo post-clang-tidy-results composite action definition. |
.github/actions/handle-fix-commit/action.yaml |
Removes the in-repo handle-fix-commit composite action definition. |
.github/actions/get-pr-info/action.yaml |
Removes the in-repo get-pr-info composite action definition. |
.github/actions/generate-build-matrix/generate_matrix.py |
Removes the in-repo helper script for generate-build-matrix. |
.github/actions/generate-build-matrix/action.yaml |
Removes the in-repo generate-build-matrix composite action definition. |
.github/actions/detect-relevant-changes/action.yaml |
Removes the in-repo detect-relevant-changes composite action definition. |
.github/actions/detect-act-env/action.yaml |
Removes the in-repo detect-act-env composite action definition. |
.github/actions/configure-cmake/action.yaml |
Removes the in-repo configure-cmake composite action definition. |
.github/actions/complete-pr-comment/action.yaml |
Removes the in-repo complete-pr-comment composite action definition. |
.github/actions/collect-format-results/action.yaml |
Removes the in-repo collect-format-results composite action definition. |
.github/actions/build-cmake/action.yaml |
Removes the in-repo build-cmake composite action definition. |
.devcontainer/post-create.sh |
Wires Kilo config content into interactive shells and seeds Kilo auth.json inside the container. |
.devcontainer/ensure-repos.sh |
Refactors socat relay setup; adds headroom proxy relay and directory setup helpers. |
.devcontainer/Dockerfile |
Installs ssh in the devcontainer image alongside podman/socat. |
.devcontainer/devcontainer.json |
Updates env/mount wiring for Kilo, adds a dedicated Kilo data volume, and tweaks settings. |
| _DEFAULT_KILO_API = os.environ.get("GIT_AI_COMMIT_KILO_API", "https://litellm.fnal.gov/v1") | ||
| _DEFAULT_MODEL_KILO = os.environ.get("GIT_AI_COMMIT_KILO_MODEL", "azure/claude-haiku-4-5") | ||
| # True when the user has explicitly pinned a kilo model via the environment, | ||
| # which suppresses auto-escalation even if the diff is large. | ||
| _KILO_MODEL_PINNED_BY_ENV = "GIT_AI_COMMIT_KILO_MODEL" in os.environ |
| # Track whether the model was explicitly chosen by the user (CLI or env). | ||
| # An explicit choice suppresses auto-escalation for large prompts. | ||
| model_explicit = bool(args.model or "GIT_AI_COMMIT_MODEL" in os.environ) | ||
| model = args.model or _default_model(backend) | ||
|
|
| def test_empty_diff_triggers_guard(self) -> None: | ||
| """An empty diff (as returned by git diff --cached with nothing staged) triggers guard.""" | ||
| assert not "".strip() | ||
|
|
||
| def test_whitespace_only_diff_triggers_guard(self) -> None: | ||
| """A diff containing only whitespace (e.g. a bare newline) also triggers the guard.""" | ||
| assert not "\n".strip() |
| # Export GitHub Actions — Operator Guide | ||
|
|
||
| This guide is self-contained. An operator (or agent) can execute Phases 2-6 | ||
| end-to-end without consulting any other document. | ||
|
|
Add automatic escalation to a high-context model (qwen3-coder-next) when the kilo backend receives large prompts (>30k chars) and the user hasn't explicitly pinned a model. This avoids degraded output or silent truncation from Haiku on large diffs without unnecessary budget spend on azure models. New features: - `_clean_message()` strips model preamble and fenced code blocks from raw API responses, normalizing responses that ignore the "respond with only the commit message" instruction - `_gh_oauth_token()` returns a genuine GitHub OAuth token (ignoring GIT_AI_COMMIT_TOKEN, which may hold a non-GitHub key like a LiteLLM API key); used for Copilot token exchange - `_KILO_MODEL_PINNED_BY_ENV` constant tracks whether the user explicitly set GIT_AI_COMMIT_KILO_MODEL, suppressing auto-escalation - `_ESCALATION_THRESHOLD_CHARS` and `_ESCALATION_MODEL_KILO` constants control escalation behavior - Improved empty-diff handling: `--amend` with no staged changes and no retrievable prior commit message now exits with a descriptive error - Increased `max_tokens` from 1024 to 2048 to accommodate longer messages - Refined system prompt to emphasize output format and prevent preamble Updated AGENTS.md to document the `read` tool parameter requirement (integer values only for `offset` and `limit`). Comprehensive test coverage in `test_git_ai_commit.py`: - `TestGhOAuthToken`: verifies GitHub OAuth token resolution - `TestCleanMessage`: validates preamble and fence stripping - `TestKiloModelPinnedByEnv`: constant existence check - `TestEmptyStagedChanges`: empty-diff guard logic Minor fix: `test_check_codeql_alerts.py` removes deprecated `strict=False` from `zip()` call (Python 3.10+ default behavior).
1. **`.github/prompts/.gitignore`** — excludes backup and checkpoint files 2. **`.github/prompts/plan-exportReusableActions.prompt.md`** — a comprehensive 1466-line operational guide for extracting 15 composite GitHub Actions from the phlex monorepo into standalone public repositories The plan document is self-contained and structured for phased execution (Phases 0–6), with dependency ordering, idempotency guards, shell scripts, and verification steps. It's the first deliverable of the action-export migration effort (superseding PR #614).
The devcontainer setup had several limitations when using headroom as a local AI proxy and when running Kilo Code alongside a Remote-SSH session. This commit addresses both: **Headroom proxy relay** Rootless Podman uses pasta for container networking, so containers reach the host via `host.docker.internal` (169.254.1.2) rather than the loopback. Pasta only maps `host.docker.internal` for ports listening on all interfaces, but headroom binds only to `127.0.0.1`. A new socat relay in `ensure-repos.sh` forwards `0.0.0.0:$HEADROOM_RELAY_PORT` → `127.0.0.1:$HEADROOM_PORT` so containers can reach the proxy. - `KILO_CONFIG_CONTENT_DOCKER` is introduced as a variant of `KILO_CONFIG_CONTENT` that rewrites the base URL to `host.docker.internal:$HEADROOM_RELAY_PORT`; `post-create.sh` exports it into `.bashrc` only when non-empty, otherwise Kilo falls back to `~/.config/kilo/kilo.jsonc` (bind-mounted from the host) - `KILO_API_KEY` (sourced from `HEADROOM_UPSTREAM_KEY`) is seeded into `/root/.local/share/kilo/auth.json` inside a container-private named volume (`phlex-kilo-data`) to avoid SQLite conflicts between the Remote-SSH and devcontainer Kilo Code instances **Refactored socat relay helper** The ad-hoc Podman socket relay logic is replaced by a reusable `start_socat_relay` function that handles killing stale processes, launching the relay with `nohup setsid`, and polling for readiness. Both the Podman and headroom relays now use this helper. **Other devcontainer fixes** - Install `ssh` in the Dockerfile so SSH-based operations work inside the container - Add `ensure_bind_dir` calls for all host-side bind-mount source paths so `initializeCommand` never fails on a fresh machine - Add a `phlex-kilo-data` named volume mount and `kilocode.new.extraCaCerts` setting to `devcontainer.json` - Reorder mounts for consistency; add empty `runArgs` for clarity
- Add `--` separator to pass remaining arguments verbatim to `git commit` - Remove dedicated `--no-verify` flag in favour of generic forwarding - Update help text and examples to show usage like `-- --no-verify --signoff` - Improve message cleaning to handle unbalanced fence markers - Add man page for `git-ai-commit(1)` with full documentation The script now splits arguments on the first `--`, forwarding everything afterwards directly to `git commit`, enabling support for any git commit option including `--no-verify`, `--signoff`, `--gpg-sign=<key>`, etc.
Install man-db, groff, and mandoc to restore documentation in the minimal Ubuntu image. Remove dpkg excludes to allow future package installs to populate man pages and docs normally. Explicitly remove the Ubuntu minimal divert of /usr/bin/man to restore the real binary. Symlink scripts/git-ai-commit into /usr/local/bin to expose it as a proper git subcommand. Add a prepend-to-manpath() helper function to .bashrc that safely prepends the repo's scripts/man directory to MANPATH while preserving system default paths. This enables `git help ai-commit` to find the man page and `git ai-commit` to work in any directory without requiring scripts/ on PATH.
90aeaf7 to
b6470d7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 53 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
.github/workflows/actionlint-check.yaml:66
.github/actions/was removed in this PR, so these relevance globs will never match anything and can be dropped to keep the actionlint-check gating accurate and easier to understand.
include-globs: |
.github/workflows/**/*.yml
.github/workflows/**/*.yaml
.github/actions/**/*.yml
.github/actions/**/*.yaml
| # there is no pre-existing MANPATH, or the existing one lacks an empty field, | ||
| # a trailing colon is appended to provide one; if an empty field already | ||
| # exists it is preserved as-is. | ||
| cat >> root/.bashrc <<'EOF' |
| # exists it is preserved as-is. | ||
| cat >> root/.bashrc <<'EOF' | ||
|
|
||
| prepend-to-manpath() { |
| esac | ||
| } | ||
|
|
||
| prepend-to-manpath "/workspaces/phlex/scripts/man" |
| # enter_context registers the file's __exit__ on the stack, so | ||
| # the file is closed automatically when the `with` block exits. | ||
| # CodeQL: py/resource-leak does not track enter_context — safe. # noqa: CodeQL[py/resource-leak] | ||
| source = stack.enter_context(open("/dev/tty")) # noqa: SIM115 |
| - name: Detect Actions changes | ||
| id: detect_actions | ||
| if: steps.should_skip.outputs.skip != 'true' | ||
| uses: Framework-R-D/phlex/.github/actions/run-change-detection@main | ||
| uses: Framework-R-D/action-run-change-detection@c70418d77a03191b165dd7dfebadbe00c443566c # v1 | ||
| with: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 53 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (1)
.github/workflows/actionlint-check.yaml:64
- The relevance-check include globs still reference
.github/actions/**, but this PR removes the.github/actions/directory. Keeping these patterns is harmless but stale, and it makes the relevance logic harder to understand going forward.
uses: Framework-R-D/action-workflow-setup@f73307dd8c13cb66c2565c9ace32571517b1cea8 # v1
with:
include-globs: |
.github/workflows/**/*.yml
.github/workflows/**/*.yaml
| print(f"Generating commit message using {model} via {backend}…", file=sys.stderr) | ||
|
|
||
| # For the copilot backend, exchange the OAuth token for a short-lived one. |
| # enter_context registers the file's __exit__ on the stack, so | ||
| # the file is closed automatically when the `with` block exits. | ||
| # CodeQL: py/resource-leak does not track enter_context — safe. # noqa: CodeQL[py/resource-leak] | ||
| source = stack.enter_context(open("/dev/tty")) # noqa: SIM115 |
| def test_empty_diff_triggers_guard(self) -> None: | ||
| """An empty diff (as returned by git diff --cached with nothing staged) triggers guard.""" | ||
| assert not "".strip() | ||
|
|
||
| def test_whitespace_only_diff_triggers_guard(self) -> None: | ||
| """A diff containing only whitespace (e.g. a bare newline) also triggers the guard.""" | ||
| assert not "\n".strip() | ||
|
|
| # Adjust MANPATH to enable `git help ai-commit` to find the man page. | ||
| # The scripts/man/man1 directory contains git-subcommand man pages. | ||
| # Prepend the repo man directory and ensure the resulting MANPATH always has | ||
| # an empty field (which tells man to search the system default paths). When | ||
| # there is no pre-existing MANPATH, or the existing one lacks an empty field, | ||
| # a trailing colon is appended to provide one; if an empty field already | ||
| # exists it is preserved as-is. | ||
| cat >> root/.bashrc <<'EOF' |
| # 127.0.0.1:$HEADROOM_PORT listener. KILO_CONFIG_CONTENT_DOCKER is set in | ||
| # ~/.bashrc and ~/.zshenv to point at host.docker.internal:$HEADROOM_RELAY_PORT. |
| - name: Detect Actions changes | ||
| id: detect_actions | ||
| if: steps.should_skip.outputs.skip != 'true' | ||
| uses: Framework-R-D/phlex/.github/actions/run-change-detection@main | ||
| uses: Framework-R-D/action-run-change-detection@c70418d77a03191b165dd7dfebadbe00c443566c # v1 | ||
| with: |
| specific labels (e.g. dependabot bumps). It does **not** run on a schedule; it is | ||
| purely a template consumed at release-creation time. Documentation: | ||
| <https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes> | ||
|
|
| **NOTE:** Verify the `rev` values for all pre-commit hooks against | ||
| `https://github.com/ORG/REPO/releases` before writing the script. Do not use | ||
| version strings from this document without checking. |
| # enter_context registers the file's __exit__ on the stack, so | ||
| # the file is closed automatically when the `with` block exits. | ||
| # CodeQL: py/resource-leak does not track enter_context — safe. | ||
| source = stack.enter_context(open("/dev/tty")) # noqa: CodeQL[py/resource-leak], SIM115 |
- Add 30-second timeout to GitHub API requests to prevent CI hangs - Distinguish SHA-1 refs from branch names when calling alerts API - Wrap base/prev commit alert fetching in try/except to allow fallback - Rename variables and debug logs from 'ak' to 'num' for clarity
| except GitHubAPIError as exc: | ||
| _debug(f"Failed to fetch base or previous commit alerts: {exc}") | ||
| # Still proceed with main vs. branch comparison | ||
| pass |
Migrates internal composite actions to standalone Framework-R-D/action-* repos. Supersedes #614. Links: see docs/dev/export-actions-plan.md.