Skip to content
This repository was archived by the owner on Jul 22, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/get-src/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ runs:
- name: checkout submodules
run: |
cd "$GITHUB_WORKSPACE"
git config --global user.email "worker@ci.ci"
git config --global user.email "ci@genlayerlabs.com"
git config --global user.name "CI worker"
if [ "${{ inputs.load_submodules }}" == "true" ]
then
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/branch_forward.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: branch / forward version to main

# main is the default branch but is only an ALIAS of the latest active
# version branch (v<latest>.x): it always points at that branch's tip and
# is never committed to directly. On every push to a version branch we
# dev branch (v<latest>-dev): it always points at that branch's tip and
# is never committed to directly. On every push to a dev branch we
# fast-forward main to it — but only for the LATEST active version, so
# parallel trains (e.g. v0.3.x and v0.6.x) don't fight over main.
# parallel trains (e.g. v0.3-dev and v0.6-dev) don't fight over main.
#
# main is protected, so the default GITHUB_TOKEN cannot push to it. We
# push over SSH with a write deploy key (GENVM_CI_PRIVATE_KEY), which must
Expand All @@ -14,7 +14,7 @@ name: branch / forward version to main

on:
push:
branches: ['v*.x']
branches: ['v*-dev']

permissions:
contents: read
Expand All @@ -35,17 +35,17 @@ jobs:
# fast-forward and the server rejects it ("fetch first").
fetch-depth: 0

- name: Fast-forward main to latest version branch
- name: Fast-forward main to latest dev branch
run: |
BRANCH="${GITHUB_REF_NAME}"
# Decide "latest" from main's active-versions (the authoritative
# alias), NOT the pushed branch's own copy — an older version
# alias), NOT the pushed branch's own copy — an older dev
# branch carries a stale active-versions and would otherwise try
# to drag main backwards once a newer train exists.
git show origin/main:.genvm-monorepo-root > /tmp/main-monorepo-root.json
LATEST="$(MONOREPO_ROOT=/tmp/main-monorepo-root.json python3 support/ci/branch-versions.py latest)"
if [ "$BRANCH" != "v${LATEST}.x" ]; then
echo "Pushed branch ${BRANCH} is not the latest version branch (v${LATEST}.x); nothing to do"
if [ "$BRANCH" != "v${LATEST}-dev" ]; then
echo "Pushed branch ${BRANCH} is not the latest dev branch (v${LATEST}-dev); nothing to do"
exit 0
fi
echo "Fast-forwarding main to ${GITHUB_SHA} (from ${BRANCH})"
Expand Down
69 changes: 69 additions & 0 deletions .github/workflows/branch_merge_into_dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: branch / merge PR into dev

# The repo has NO GitHub merge queue. A PR lands on a dev branch (v<X>-dev)
# when a maintainer ticks the "Merge" box on the PR action panel
# (branch_pr_actions.yaml), which calls this reusable workflow. It
# re-checks every gate against the EXACT head commit and then advances the
# dev branch by a plain (fast-forward-only) push, so what lands is
# byte-identical to what CI and E2E validated.
#
# Gates (all required):
# 1. base branch is a v<X>-dev branch
# 2. PR carries the `rtm` (ready-to-merge) label
# 3. full GenVM CI (queue.yaml) concluded success on the head commit
# 4. the cross-repo E2E check concluded success on the head commit
# 5. the PR is 0 commits behind base (head already contains base tip)
#
# Merge strategy:
# - 1 commit -> fast-forward the original commit (SHA preserved)
# - more than 1 commit -> squash into a single commit on top of base,
# then fast-forward
# Either way the PR is closed afterwards.
#
# The dev branches are protected; the default GITHUB_TOKEN cannot push to
# them. We push over SSH with the GENVM_CI_PRIVATE_KEY deploy key (on the
# dev-branch ruleset bypass list). Pushes are non-force, so a base that
# advanced between the checks and the push is safely rejected. This job
# never runs PR code — only git plumbing and API reads. The caller is
# responsible for restricting who can trigger a merge (maintainers only).

on:
workflow_call:
inputs:
pr_number:
description: number of the PR to merge
type: string
required: true

permissions:
contents: read
pull-requests: write
issues: write
checks: read
actions: read

defaults:
run:
shell: bash -x {0}

env:
# check-run name (case-insensitive substring) the genlayer-e2e pipeline
# posts on the head commit. Adjust if that pipeline renames its check.
E2E_CHECK_PATTERN: "e2e"

jobs:
merge:
runs-on: ubuntu-latest
steps:
# Checkout with the deploy key so the (protected) dev branch push in
# the merge script succeeds. The script never runs PR code.
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.GENVM_CI_PRIVATE_KEY }}
fetch-depth: 0

- name: Validate gates, fast-forward / squash, close
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ inputs.pr_number }}
run: python3 support/ci/genvm-merge-into-dev.py
59 changes: 59 additions & 0 deletions .github/workflows/branch_pr_actions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: branch / PR action panel handler

# Reacts to a maintainer ticking a box on the GenVM PR action panel (posted
# by branch_pr_checklist.yaml). The `dispatch` job authenticates the editor,
# parses the ticked boxes, performs label-based actions (run / rerun full
# tests), unticks the boxes, and reports whether Merge was requested. If so
# the `merge` job calls the reusable merge workflow.
#
# Resetting the panel re-fires issue_comment:edited, but that re-run finds
# no ticked box (and is sent by the bot), so it is a no-op — no loop.

on:
issue_comment:
types: [edited]

permissions:
contents: read
pull-requests: write
issues: write
actions: write
checks: read

concurrency:
group: pr-actions-${{ github.event.issue.number }}
cancel-in-progress: false

defaults:
run:
shell: bash -x {0}

jobs:
dispatch:
# Only the panel comment, only on a PR.
if: >
github.event.issue.pull_request &&
contains(github.event.comment.body, '<!-- genvm-actions -->')
runs-on: ubuntu-latest
outputs:
merge: ${{ steps.act.outputs.merge }}
steps:
# Checkout of the default branch only — to run the handler script. No
# PR code is executed.
- uses: actions/checkout@v4
- name: Handle ticked boxes
id: act
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}
COMMENT_ID: ${{ github.event.comment.id }}
SENDER: ${{ github.event.sender.login }}
run: python3 support/ci/pr-action-panel.py

merge:
needs: dispatch
if: needs.dispatch.outputs.merge == 'true'
uses: ./.github/workflows/branch_merge_into_dev.yaml
with:
pr_number: ${{ github.event.issue.number }}
secrets: inherit
67 changes: 67 additions & 0 deletions .github/workflows/branch_pr_checklist.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: branch / post PR action panel

# When a PR is opened against a dev branch (v<X>-dev) we:
# - make sure the action labels exist;
# - post the action panel (checklist comment) that replaces the old
# /genvm-* slash commands;
# - auto-add `ci-safe` if the PR author has write access, so their PR can
# immediately use the panel. For everyone else a write-role maintainer
# adds `ci-safe` by hand once the PR is vetted.
#
# pull_request_target gives a write-scoped token even for fork PRs; we only
# call label/comment APIs and never check out or run PR code. The HTML
# marker lets branch_pr_actions.yaml recognise the panel later.

on:
pull_request_target:
branches: ['v*-dev']
types: [opened]

permissions:
pull-requests: write
issues: write

defaults:
run:
shell: bash -x {0}

jobs:
post:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
steps:
- name: Ensure action labels exist
run: |
gh label create rtm -R "$GITHUB_REPOSITORY" --color 0e8a16 --description "ready to merge" 2>/dev/null || true
gh label create run-full-tests -R "$GITHUB_REPOSITORY" --color fbca04 --description "run full GenVM CI on every push" 2>/dev/null || true
gh label create ci-safe -R "$GITHUB_REPOSITORY" --color 5319e7 --description "PR cleared to run CI / panel actions" 2>/dev/null || true

- name: Post action panel
run: |
gh pr comment "$PR" --repo "$GITHUB_REPOSITORY" --body "$(cat <<'EOF'
<!-- genvm-actions -->
### GenVM PR actions

Tick a box to run it (the box unticks itself when handled). Actions only run while the PR has the **`ci-safe`** label.

- [ ] Force run full tests
- [ ] Rerun full tests
- [ ] Merge into dev

<sub>Full GenVM CI runs only when **`rtm`** or **`run-full-tests`** is set — "Force run full tests" is a sticky toggle for `run-full-tests`. Adding **`rtm`** marks the PR ready-to-merge and also runs full tests. **Merge** requires: `rtm`, green full tests, green E2E, and the branch 0 commits behind.</sub>
EOF
)"

- name: Auto-mark ci-safe for write-access authors
run: |
perm="$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$AUTHOR/permission" --jq '.permission' 2>/dev/null || echo none)"
case "$perm" in
admin|write|maintain)
echo "author $AUTHOR has '$perm' access; marking ci-safe"
gh api --method POST "repos/$GITHUB_REPOSITORY/issues/$PR/labels" -f 'labels[]=ci-safe' ;;
*)
echo "author $AUTHOR has '$perm' access; leaving unmarked (a write-role maintainer must add ci-safe)" ;;
esac
35 changes: 0 additions & 35 deletions .github/workflows/branch_queue_guard.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/branch_retarget.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ jobs:
gh pr comment "$PR" --repo "$GITHUB_REPOSITORY" --body "$(cat <<EOF
👋 This PR targeted \`main\`, so I've retargeted it to the latest dev branch \`${DEV}\`.

\`main\` is protected and is only an alias of the latest release branch (\`v${LATEST}.x\`), kept in lockstep automatically. Active v${LATEST} work lands on \`${DEV}\`, which reaches \`v${LATEST}.x\` through the standing release-gate PR once the cross-repo E2E matrix is green.
\`main\` is protected and is only an alias of the latest release branch (\`v${LATEST}-dev\`), kept in lockstep automatically. Active v${LATEST} work lands on \`${DEV}\`, which reaches \`v${LATEST}.x\` through the standing release-gate PR once the cross-repo E2E matrix is green.
EOF
)"
28 changes: 28 additions & 0 deletions .github/workflows/incl_initial.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,31 @@ jobs:
- uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files --show-diff-on-failure

# The Merge action only fast-forwards, so the PR head must already
# contain the base tip (0 commits behind). We assert it here too (as part
# of the always-on `initial` checks) so the gate goes red the moment the
# branch falls behind, instead of surfacing only at merge time.
behind-check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure 0 commits behind base
env:
BASE: ${{ github.event.pull_request.base.ref }}
PR: ${{ github.event.pull_request.number }}
run: |
# Resolve base tip and PR head via explicit refs so this also
# works for fork PRs (head.sha is not fetchable by sha there).
git fetch --no-tags origin \
"+refs/heads/${BASE}:refs/base" \
"refs/pull/${PR}/head:refs/prhead"
if ! git merge-base --is-ancestor refs/base refs/prhead; then
BEHIND="$(git rev-list --count refs/prhead..refs/base)"
echo "::error::PR is ${BEHIND} commit(s) behind ${BASE}; update/rebase the branch so it is 0 behind before merging"
exit 1
fi
echo "0 commits behind ${BASE}"
53 changes: 0 additions & 53 deletions .github/workflows/pr.yaml

This file was deleted.

Loading
Loading