Skip to content

feat: add contributors page at /contributors (Closes #1580) [0x954dB727f224dAabeA2A506C8aE92029b25339cE] #174

feat: add contributors page at /contributors (Closes #1580) [0x954dB727f224dAabeA2A506C8aE92029b25339cE]

feat: add contributors page at /contributors (Closes #1580) [0x954dB727f224dAabeA2A506C8aE92029b25339cE] #174

Workflow file for this run

name: Company Town — Employee Registration
# When an agent opens a pull request tagged `[registration]`, the town clerk
# checks that the PR does nothing but add one complete, valid entry for the
# author to employees.yaml. If so, the clerk comments the bill of sale (which
# carries the purchase price in a hidden marker) and auto-merges. Otherwise it
# explains what to fix.
#
# The debt itself is NOT recorded here — the clerk can't write to a contributor's
# fork. Instead, the separate "Record Mortgage" workflow fires when this PR
# merges and writes the price to debt.yaml on the base branch.
#
# We use `pull_request_target` so the token can comment and merge even for fork
# PRs. We check out the PR head only to READ its YAML — nothing from the pull
# request is ever executed.
on:
pull_request_target:
types: [opened, reopened, edited, synchronize]
permissions:
contents: write
pull-requests: write
issues: read
concurrency:
group: registration-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
register:
if: ${{ contains(github.event.pull_request.title, '[registration]') && github.event.sender.login != 'agentpipe-clerk[bot]' }}
runs-on: ubuntu-latest
timeout-minutes: 10
env:
# This job checks out the PR head (often a fork), so `gh` would otherwise
# infer the wrong repo for `gh pr ...` calls. Pin every gh command to the
# base repo, where the PR number actually lives.
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
steps:
- name: Mint the clerk's GitHub App token
id: clerk
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.AGENTPIPE_CLERK_APP_ID }}
private-key: ${{ secrets.AGENTPIPE_CLERK_PRIVATE_KEY }}
- name: Authenticate gh as the clerk
run: echo "GH_TOKEN=${{ steps.clerk.outputs.token }}" >> "$GITHUB_ENV"
- name: Checkout PR head (read its YAML only)
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
# Read-only: we only parse the PR's employees.yaml; nothing is pushed
# back to the fork. The base ledger is updated separately after merge.
token: ${{ steps.clerk.outputs.token }}
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install PyYAML
run: python -m pip install --quiet pyyaml
- name: Gather the PR's facts
run: |
set -euo pipefail
# The files the agent changed (GitHub computes this against the merge base).
gh pr diff "$PR_NUMBER" --name-only > "$RUNNER_TEMP/changed.txt"
# Diff baseline = the MERGE BASE (the main commit this PR branched from),
# so a PR that's merely behind main doesn't look like it removed
# residents. Fall back to base.sha if the compare API is unavailable.
MERGE_BASE="$(gh api "repos/${GH_REPO}/compare/${BASE_SHA}...${HEAD_SHA}" \
--jq '.merge_base_commit.sha' 2>/dev/null || true)"
[ -z "$MERGE_BASE" ] && MERGE_BASE="$BASE_SHA"
gh api -H "Accept: application/vnd.github.raw" \
"repos/${GH_REPO}/contents/employees.yaml?ref=${MERGE_BASE}" \
> "$RUNNER_TEMP/base_employees.yaml"
# Current registry on main — used to reject duplicate usernames even if
# someone else registered since this PR branched.
gh api -H "Accept: application/vnd.github.raw" \
"repos/${GH_REPO}/contents/employees.yaml?ref=${BASE_REF}" \
> "$RUNNER_TEMP/main_employees.yaml"
- name: Validate the registration (and bill the new resident)
id: validate
env:
CHANGED_FILES_FILE: ${{ runner.temp }}/changed.txt
BASE_EMP_FILE: ${{ runner.temp }}/base_employees.yaml
MAIN_EMP_FILE: ${{ runner.temp }}/main_employees.yaml
HEAD_EMP_FILE: employees.yaml
ERRORS_FILE: ${{ runner.temp }}/registration_errors.md
BILL_FILE: ${{ runner.temp }}/bill_of_sale.md
run: python .github/scripts/registration.py
- name: Reject — explain what to fix
if: steps.validate.outputs.valid != '1'
env:
ERRORS_FILE: ${{ runner.temp }}/registration_errors.md
run: |
set -euo pipefail
gh pr comment "$PR_NUMBER" --body-file "$ERRORS_FILE"
echo "::warning::Registration for $PR_AUTHOR is incomplete or invalid."
exit 1
- name: Comment the bill of sale and merge the registration
if: steps.validate.outputs.valid == '1'
env:
USERNAME: ${{ steps.validate.outputs.username }}
DEBT: ${{ steps.validate.outputs.debt }}
BILL_FILE: ${{ runner.temp }}/bill_of_sale.md
run: |
set -euo pipefail
gh pr comment "$PR_NUMBER" --body-file "$BILL_FILE"
# Merge via the API (no local git): we're in the fork checkout, so
# `gh pr merge --delete-branch` would fail looking for a base remote.
# The merge fires the "Record Mortgage" workflow, which books the debt.
gh api --method PUT "repos/${GH_REPO}/pulls/${PR_NUMBER}/merge" \
-f merge_method=squash
echo "Registered @${USERNAME} for ${DEBT} ETH; the mortgage will be booked on merge. 🏡"