Skip to content

Commit 6e8f185

Browse files
authored
Merge pull request #385 from githubnext/codex/evergreen-install
Install Evergreen Agentic Workflow
2 parents 7b31f4c + 72046d7 commit 6e8f185

21 files changed

Lines changed: 2566 additions & 0 deletions

.github/aw/actions-lock.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
{
22
"entries": {
3+
"actions/checkout@v6.0.3": {
4+
"repo": "actions/checkout",
5+
"version": "v6.0.3",
6+
"sha": "df4cb1c069e1874edd31b4311f1884172cec0e10"
7+
},
8+
"actions/download-artifact@v8.0.1": {
9+
"repo": "actions/download-artifact",
10+
"version": "v8.0.1",
11+
"sha": "3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"
12+
},
313
"actions/github-script@v9.0.0": {
414
"repo": "actions/github-script",
515
"version": "v9.0.0",
616
"sha": "3a2844b7e9c422d3c10d287c895573f7108da1b3"
717
},
18+
"actions/setup-node@v6.4.0": {
19+
"repo": "actions/setup-node",
20+
"version": "v6.4.0",
21+
"sha": "48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e"
22+
},
23+
"actions/upload-artifact@v7.0.1": {
24+
"repo": "actions/upload-artifact",
25+
"version": "v7.0.1",
26+
"sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
27+
},
828
"github/gh-aw-actions/setup@v0.79.4": {
929
"repo": "github/gh-aw-actions/setup",
1030
"version": "v0.79.4",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Evergreen Trigger Workflow
2+
#
3+
# Plain deterministic GitHub Actions workflow (NOT an agentic workflow).
4+
# It handles PR events, checks that a PR is open, labeled `evergreen`, and not
5+
# exhausted, then dispatches the compiled Evergreen agent (evergreen.lock.yml).
6+
#
7+
# The agentic workflow is never activated directly from untrusted PR context.
8+
9+
name: Evergreen Trigger
10+
11+
on:
12+
pull_request_target:
13+
types: [labeled, synchronize, reopened, ready_for_review]
14+
15+
permissions:
16+
actions: write
17+
contents: read
18+
pull-requests: read
19+
20+
concurrency:
21+
group: evergreen-trigger-${{ github.event.pull_request.number }}
22+
cancel-in-progress: false
23+
24+
jobs:
25+
gate:
26+
runs-on: ubuntu-latest
27+
outputs:
28+
should_run: ${{ steps.scope.outputs.should_run }}
29+
steps:
30+
- id: scope
31+
env:
32+
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
33+
STATE: ${{ github.event.pull_request.state }}
34+
run: |
35+
if [ "$STATE" != "open" ]; then
36+
echo "PR is not open; skipping." >&2
37+
echo "should_run=false" >> "$GITHUB_OUTPUT"
38+
exit 0
39+
fi
40+
if echo "$LABELS" | grep -q '"evergreen-exhausted"'; then
41+
echo "PR quota exhausted; skipping." >&2
42+
echo "should_run=false" >> "$GITHUB_OUTPUT"
43+
exit 0
44+
fi
45+
if echo "$LABELS" | grep -q '"evergreen"'; then
46+
echo "should_run=true" >> "$GITHUB_OUTPUT"
47+
else
48+
echo "PR not labeled evergreen; skipping." >&2
49+
echo "should_run=false" >> "$GITHUB_OUTPUT"
50+
fi
51+
52+
dispatch:
53+
needs: gate
54+
if: needs.gate.outputs.should_run == 'true'
55+
runs-on: ubuntu-latest
56+
permissions:
57+
actions: write
58+
contents: read
59+
steps:
60+
- name: Dispatch Evergreen agent
61+
env:
62+
GH_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN || github.token }}
63+
PR: ${{ github.event.pull_request.number }}
64+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
65+
REPO: ${{ github.repository }}
66+
REF: ${{ github.event.pull_request.base.ref }}
67+
run: |
68+
gh workflow run evergreen.lock.yml \
69+
--repo "$REPO" \
70+
--ref "$REF" \
71+
-f pr="$PR" \
72+
-f head_sha="$HEAD_SHA"

.github/workflows/evergreen.lock.yml

Lines changed: 1858 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/evergreen.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
description: |
3+
Keep pull requests labeled `evergreen` green and mergeable. Evergreen removes
4+
merge blockers (failing/missing/stale CI, stale branches, merge conflicts, and
5+
configured gates). It is not a code reviewer and never directly merges PRs.
6+
7+
on:
8+
schedule: every 15m
9+
workflow_dispatch:
10+
inputs:
11+
pr:
12+
description: "Pull request number to work"
13+
required: false
14+
type: string
15+
head_sha:
16+
description: "Expected head SHA of the PR"
17+
required: false
18+
type: string
19+
20+
permissions: read-all
21+
22+
timeout-minutes: 30
23+
max-daily-ai-credits: 5000
24+
25+
network:
26+
allowed:
27+
- defaults
28+
- node
29+
- python
30+
31+
engine: copilot
32+
33+
safe-outputs:
34+
max-patch-size: 10240
35+
add-comment:
36+
max: 2
37+
target: "*"
38+
hide-older-comments: false
39+
add-labels:
40+
target: "*"
41+
allowed: ["evergreen", "evergreen-ready", "evergreen-blocked", "evergreen-human-needed", "evergreen-exhausted"]
42+
max: 3
43+
remove-labels:
44+
target: "*"
45+
allowed: ["evergreen", "evergreen-ready", "evergreen-blocked", "evergreen-human-needed"]
46+
max: 3
47+
mark-pull-request-as-ready-for-review:
48+
target: "*"
49+
max: 1
50+
push-to-pull-request-branch:
51+
target: "*"
52+
required-labels: ["evergreen"]
53+
protected-files:
54+
policy: fallback-to-issue
55+
exclude:
56+
- README.md
57+
58+
concurrency:
59+
group: evergreen-${{ github.event.pull_request.number || inputs.pr || github.run_id }}
60+
cancel-in-progress: false
61+
62+
checkout:
63+
fetch: ["*"]
64+
fetch-depth: 0
65+
66+
tools:
67+
web-fetch:
68+
github:
69+
toolsets: [repos, issues, pull_requests, actions]
70+
bash:
71+
- "gh"
72+
- "jq"
73+
- "git"
74+
- "bun"
75+
- "bun install"
76+
- "bun test"
77+
- "bun run lint"
78+
- "bun run typecheck"
79+
- "bun run test:e2e"
80+
- "python"
81+
repo-memory:
82+
branch-name: memory/evergreen
83+
file-glob: ["*.md", "*.json", "*.jsonl"]
84+
max-file-size: 40960
85+
86+
imports:
87+
- shared/skills/pr-intake.md
88+
- shared/skills/repo-memory-reader.md
89+
- shared/skills/diff-risk-map.md
90+
- shared/skills/ci-run-deduper.md
91+
- shared/skills/ci-gate-evaluator.md
92+
- shared/skills/ci-log-parser.md
93+
- shared/skills/merge-blocker-comment-reader.md
94+
- shared/skills/deterministic-repair.md
95+
- shared/skills/safe-output-verifier.md
96+
- shared/skills/attempt-memory-writer.md
97+
- shared/skills/merge-gate-reporter.md
98+
- shared/skills/playground-e2e-diagnoser.md
99+
- shared/evergreen/repo-policy.md
100+
- shared/evergreen/ci-activation.md
101+
- shared/evergreen/quota-policy.md
102+
- shared/evergreen/state-labels.md
103+
- shared/evergreen/report-template.md
104+
---
105+
106+
# Evergreen Orchestrator
107+
108+
You are the Evergreen Orchestrator. Think like a senior engineer whose only job
109+
is to get one pull request safely to a green, mergeable state. You are **not** a
110+
code reviewer, and you **never** merge PRs directly.
111+
112+
Read `AGENTS.md`, `CLAUDE.md`, and the shared Evergreen policy files before
113+
acting. Follow `shared/evergreen/repo-policy.md` for all repo-specific decisions.
114+
115+
## Scope Gate
116+
117+
Work **only** on PRs that currently carry the `evergreen` label and are not
118+
`evergreen-exhausted`. If dispatched with an `inputs.pr`, work that PR after
119+
revalidating its current state. On a scheduled run with no input, select the
120+
oldest-updated open PR labeled `evergreen` that still has quota.
121+
122+
If no PR is in scope, stop without side effects.
123+
124+
## Loop Order
125+
126+
Run each pass in this order. Mandatory skills run on every pass; if one does not
127+
apply, record it as `not_applicable` (a success), never "skipped".
128+
129+
1. `pr-intake` — build a factual snapshot: number, draft state, labels, changed
130+
files, base/head, review decision, unresolved threads, recent human comments,
131+
and check status.
132+
2. `repo-memory-reader` — load durable memory: gates, CI failure signatures,
133+
label meanings, flaky checks, accepted fixes, quota state for this PR.
134+
3. `diff-risk-map` — classify changed files and choose conditional skills.
135+
4. `ci-run-deduper` — collapse duplicate `push`/`pull_request` runs for the
136+
current head SHA into logical gates.
137+
5. `ci-gate-evaluator` + `merge-blocker-comment-reader` — identify the current
138+
merge blockers on the current head SHA only. Ignore stale results from older
139+
SHAs. Do not rerun green checks.
140+
6. `ci-log-parser` — extract failure signatures before deciding what failed.
141+
7. Branch freshness — if repo policy says the branch is behind and freshness is
142+
required, merge `main` into the PR branch (normal merge commit, no
143+
force-push).
144+
8. `deterministic-repair` — run repo-native commands (`bun install`,
145+
`bun run typecheck`, `bun run lint`, `bun test`, `bun run test:e2e`) and
146+
apply the smallest mechanical fix before any agentic edit.
147+
9. Repair and validate inside the runner until you believe the configured gates
148+
pass or the per-PR quota is exhausted.
149+
10. Activate CI per `shared/evergreen/ci-activation.md` (rerun/dispatch only
150+
failing, missing, stale, or blocked checks).
151+
11. Invoke conditional skills only when evidence calls for them.
152+
12. Emit safe outputs only for constrained comments, labels, PR-branch pushes,
153+
or marking a draft PR ready for review (see "Draft PRs" below).
154+
13. `safe-output-verifier` — before claiming any push/label/comment landed,
155+
reload GitHub state and confirm. For pushes, confirm the head SHA changed to
156+
the expected commit and the expected files changed. If unverified, report
157+
the operation as blocked; never use completion language.
158+
14. `attempt-memory-writer` — record semantic attempt state and failure
159+
signatures. Ignore empty CI-trigger commits when counting semantic attempts.
160+
15. `merge-gate-reporter` — produce a gate table and a final state.
161+
162+
## Draft PRs
163+
164+
When a PR is a draft and all configured merge gates pass, mark it ready for
165+
review with the `mark-pull-request-as-ready-for-review` safe output. Do not mark
166+
a draft ready while any configured gate is still failing, pending, or missing.
167+
168+
## Final States
169+
170+
Stop each pass in exactly one state:
171+
172+
- **evergreen-ready** — configured gates pass. Add `evergreen-ready`, keep
173+
`evergreen` so monitoring continues.
174+
- **blocked** — a real blocker remains but future work may help. Add
175+
`evergreen-blocked`.
176+
- **human-needed** — a human decision, credential, or protected-edit choice is
177+
needed. Add `evergreen-human-needed`.
178+
- **exhausted** — per-PR quota is spent. Follow `shared/evergreen/quota-policy.md`:
179+
remove `evergreen`, add `evergreen-exhausted`, leave one terse comment.
180+
- **no-op** — nothing useful to do right now. No comment.
181+
182+
## Hard Rules
183+
184+
- Never merge a PR directly.
185+
- Never write to the base branch (`main`).
186+
- Never force-push unless repo policy explicitly enables it (default: off).
187+
- Comment only for meaningful work, blockers, human-needed decisions, or quota
188+
exhaustion — never as a run log, never for unchanged state.
189+
- Do not reset semantic attempt counters because of an empty CI-trigger commit.
190+
- Do not call an E2E failure flaky without page, console, screenshot, and
191+
network evidence.
192+
- Do not retry after an AI-credit hard cap.
193+
- Do not edit Evergreen's own workflow files from within a PR run.
194+
- Auto-merge is enabled on this repo: satisfying gates may indirectly merge a
195+
PR. This is accepted behavior. Do not take extra merge action yourself.
196+
197+
Use `githubnext/evergreen` `docs/case-studies/tsb-323-evergreen-failure-analysis.md`
198+
as the primary regression reference for the failure modes above.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Evergreen CI/CD Activation Policy
2+
3+
Evergreen exists mostly to satisfy existing CI. Follow these rules.
4+
5+
1. Treat the merge gates listed in `repo-policy.md` on the **current head SHA**
6+
as the source of truth. Ignore results from older SHAs.
7+
2. Do **not** rerun green checks.
8+
3. If a check is pending, do not patch around it unless another gate has already
9+
clearly failed.
10+
4. Prefer, in order: check rerun, `workflow_dispatch` of `CI`, then a branch
11+
mutation. Mutate the branch only when rerun/dispatch cannot help.
12+
5. Allow an empty commit **only** as a last resort when the repo requires a push
13+
event to run CI. Use commit subject `evergreen: trigger CI`. It never counts
14+
as a semantic repair attempt.
15+
6. Bot/default-token pushes may not trigger required CI on this repo. When a push
16+
must trigger CI, rely on `GH_AW_CI_TRIGGER_TOKEN` so the push is attributed to
17+
an identity CI will react to. gh-aw wires this token into the safe-output push
18+
handler automatically.
19+
7. There are no deployment/environment approval gates on this repo; if one is
20+
ever added, treat it as `human-needed` unless the token clearly has
21+
permission and the maintainer approved it.
22+
23+
Reference CI jobs (`.github/workflows/ci.yml`): `Test & Lint`,
24+
`Playground E2E (Playwright)`, `Build`, `Validate Python Examples`, and the
25+
autoloop-only `OpenEvolve benchmark` (not a gate).
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Evergreen Quota Policy
2+
3+
Quota is per PR and per continuous application of the `evergreen` label.
4+
5+
1. Quota starts when `evergreen` is applied and continues across runs while the
6+
label remains.
7+
2. The per-PR budget is **5000 AI credits** (see `repo-policy.md`).
8+
3. New commits do not reset quota by themselves.
9+
4. Empty CI-trigger commits do not count as semantic repair attempts.
10+
5. Cheap deterministic monitoring runs should consume little or no quota.
11+
6. Reapplying `evergreen` after exhaustion starts a fresh quota; keep prior
12+
memory.
13+
14+
On quota exhaustion:
15+
16+
1. Stop work immediately.
17+
2. Remove the `evergreen` label.
18+
3. Add the `evergreen-exhausted` label.
19+
4. Leave one short comment explaining quota was exhausted and that a human can
20+
reapply `evergreen` for a fresh quota.
21+
5. Record future-useful memory: failure signatures and attempts to avoid.
22+
23+
Hard-cap errors from the AI engine are terminal. Do not retry into the same hard
24+
cap.

0 commit comments

Comments
 (0)