Skip to content
cgwalters-forgePublic

About

GitHub Actions shared by cgwalters-forge workflows (secure-host-setup, tailscale)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

actions

GitHub Actions for cgwalters-forge and bootc-dev workflows, one per directory, used as cgwalters-forge/actions/<name>@main. Work items are this repository's issues.

Action Status Roadmap
lint actionlint, zizmor and the runner-label policy; this repository's CI calls it Called from each forge repository's CI
workflows-check Required workflow over a pull request's workflow files: job shape, new dangerous triggers, new zizmor ignores, checker references; CI runs its tests with fixture workflows An organization ruleset requires it, evaluate mode first
secure-host Runs agentic-job's attested, digest-pinned image: no later step has root or the metadata service, world-write by owner only; CI runs the two-job example, the inputs and the world-write policy on ubuntu-26.04 agentic-job's own action forwards here; opt-in egress (agentic-job#995)
app-token Mints and masks one role's GitHub App installation token, scoped to named repositories; remint.mjs mints again near expiry or after a 401; CI runs its unit tests, no real mint (no app here) Move each role to its app (tracker#766)
tailscale Settings by organization; CI runs its unit tests and checks the socket and CLI are closed after a join that fails, no real join (no tailnet credentials here) Replace devspace.yml's and agent.yml's tailscale/github-action steps

cgwalters-agentic-job

One reusable workflow is here too: cgwalters-agentic-job, an agent run of cgwalters-forge/agentic-job with this deployment's tailnet join, inference proxy, runner, agent and model. Our repositories call it at main, which is the one job_workflow_ref the inference broker and the tailnet have to admit. It refuses runs from a private repository, so agentic-job's opt-in for private repositories, which admits only the calling repository, stays off.

A repository gets agent runs with the workflow below, a bounds file at .github/agentic-job/dispatch.toml (and fix.toml for the fix kind), a runner configuration at .github/agentic-job/hosted.toml, and an environment that gates the apply token; cgwalters-forge/tracker has all four to copy. The file's header says what else a caller may set.

Both wrappers pin agentic-job v0.6.2 and check inference reachability after the tailnet join, before securing the host. They still compose that tag's secure-host/internal action, which runs sandbox setup on the host, not this repository's secure-host image action that the tag's public secure-host now forwards to, so its egress proxy stays a host unit. Since v0.6.0 the agent's home no longer copies the runner image's /etc/skel, toolchains and dotfiles included. The pinned run action publishes the session endpoint itself; no extra endpoint step is needed here. Mid-run steering stays off unless the caller's runner configuration enables [session] watch-item = true. Policy derives the watched item from the dispatch wrapper's issue (in output-repo) or the review event; run needs no additional input. Upstream bounds delivery to 10 updates of 8000 characters, quoted as untrusted item text, not instructions.

name: dispatch
run-name: ${{ inputs.kind }} ${{ inputs.repo }}#${{ inputs.item }}
on:
  workflow_dispatch:
    inputs:
      task: {type: string, required: true}
      repo: {type: string, required: true}
      item: {type: string, required: true}
      kind: {type: choice, required: true, options: [implement, triage, research, review, fix]}
permissions: {}
concurrency:
  group: dispatch-${{ inputs.kind }}-${{ inputs.repo }}-${{ inputs.item }}
jobs:
  run:
    uses: cgwalters-forge/actions/.github/workflows/cgwalters-agentic-job.yml@main
    permissions: {contents: read, issues: write, pull-requests: write, actions: read, id-token: write}
    with:
      task: ${{ inputs.task }}
      repo: ${{ inputs.repo }}
      item: ${{ inputs.item }}
      kind: ${{ inputs.kind }}
      apply-environment: agent-apply
    secrets:
      SAFE_OUTPUTS_PAT: ${{ secrets.CGWALTERS_BOT_PAT }}

Review

cgwalters-review is the reusable event-review wrapper. It composes agentic-job v0.6.2's policy, check, apply and review helpers, so that the tailnet and the inference broker admit this file's job_workflow_ref; agentic-job's review workflow can now run a caller's own network step instead (its #705), which callers have not moved to. It refuses private repositories, as the dispatch wrapper does. It adds our tailnet join and defaults: opencode, praxis/gpt-6.1-sol, ubuntu-26.04, and the dispatch wrapper's inference URL and audience. It has no inputs. Repository/organization variables AGENT, AGENT_MODEL, AGENT_RUNNER (JSON), INFERENCE_URL, INFERENCE_AUDIENCE, AGENT_CONFIG, AGENT_CONFIG_REPO and AGENT_CONFIG_PATH select owner-controlled configuration. Set the last two for agents needing external configuration; there is no hard-coded configuration repository. AGENT_CONFIG otherwise uses the pinned agentic-job hosted configuration.

Call it from the same pull_request_target and issue_comment events and job condition as this repository's caller, replacing the job's uses with:

uses: cgwalters-forge/actions/.github/workflows/cgwalters-review.yml@main

Keep that caller's six permission grants. Optional SAFE_OUTPUTS_PAT is forwarded explicitly, only to apply; it never reaches the agent or the real review submission. Keep workflow/review.toml, workflow/review-command.toml and workflow/review.md on the caller's base branch. Automatic reviews admit non-draft owner/member/collaborator PRs, preserving upstream's association rule for all authors. Otherwise-unassociated bots wait unless REVIEW_BOT_IDS lists their numeric IDs and the bounds admit their logins (including Dependabot). Use a JSON array of numbers; Actions also coerces string IDs. /review still requires write access through event policy. Only admitted agent jobs enter per-PR concurrency; new automatic events cancel the old agent, comments do not. The head is data inside the sandbox, never executed by a privileged step. Each review is bounded to 150 requests, 500 AIC and 75 agent minutes.

AGENT_REAL_REVIEWS=true opts into checked APPROVE/REQUEST_CHANGES submission with the job token, at the admitted head; unset is off. Enable GitHub Actions' permission to create/approve PRs for this feature. A stale head, cancellation or failed check cannot produce a new approval. The compatibility review status is not a merge gate or human approval.

Before migrating tracker (a separate repository), admit this wrapper's job_workflow_ref in the tailnet federation and inference broker, then replace its review caller's uses as above and exercise a real review and a synchronize cancellation. No ACL, OAuth or broker policy is changed here; record those deployment changes in the private wiki when made. Removing the deployment-specific pieces from agentic-job is a separate follow-up. just test-review checks the wrapper's admission and publication boundaries; live tailnet joins and GitHub review writes are not exercised locally.

Runs may edit .github/ here, so pull requests are reviewed by this repository's caller of the wrapper above, referenced locally so that it runs as on the base branch, never as a pull request edits it, with this repository's bounds and task in workflow/. The ruleset on main is to require its approval, dismissed when new commits are pushed; the approval is submitted only with the repository variable AGENT_REAL_REVIEWS=true, beside the variables listed above. Dependabot's pull requests are reviewed only with its ID in REVIEW_BOT_IDS. Without .github/agentic-job/merge.toml the reviewer is told a person approves after it.

Lock new items

lock-new-items locks each newly opened issue, so that only collaborators can comment on it and agent runs on it read no outsider's comments (tracker#733). Its one step locks the item by API with the caller's job token: no PAT, and nothing of the item is read or run. Pull requests are not locked: a locked PR refuses reviews from the review job token, and the supervisor only dispatches issues. It does not cover the opener's own text, comments in the seconds before the lock, items opened by another workflow's job token or transferred in (no opened event), or items that predate the caller. A repository opts in with this one file, .github/workflows/lock.yml, as this repository's caller but for its uses:

name: lock
on:
  issues:
    types: [opened]
permissions: {}
jobs:
  lock:
    uses: cgwalters-forge/actions/.github/workflows/lock-new-items.yml@main
    permissions:
      issues: write

The same pull request exempts the file in .github/agentic-job/workflows.toml, creating it if need be, as this repository does: without that, workflows-check's shape check refuses every later pull request. Its zizmor needs the ref-pin policy for our own workflows that .github/zizmor.yml sets.

Licensed under either of Apache-2.0 or MIT, at your option.

About

GitHub Actions shared by cgwalters-forge workflows (secure-host-setup, tailscale)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages