Skip to content

ci: sync agents to ct password manager (#10) #10

ci: sync agents to ct password manager (#10)

ci: sync agents to ct password manager (#10) #10

Workflow file for this run

name: Sync AGENTS.md
on:
push:
branches:
- main
paths:
- AGENTS.md
- sync-targets.txt
- .github/workflows/sync-agents.yml
workflow_dispatch:
permissions:
contents: read
concurrency:
group: sync-agents
cancel-in-progress: false
jobs:
sync:
name: Open downstream sync PRs
runs-on: self-hosted
env:
GH_TOKEN: ${{ secrets.AGENTS_SYNC_TOKEN }}
BRANCH_NAME: chore/sync-shared-agent-instructions-${{ github.run_id }}
COMMIT_MESSAGE: "docs: sync shared agent instructions"
PR_TITLE: "docs: sync shared agent instructions"
steps:
- name: Checkout source
uses: actions/checkout@v6
- name: Validate sync token
run: |
if [ -z "${GH_TOKEN}" ]; then
echo "AGENTS_SYNC_TOKEN is required. Create a repository secret with write access to the target repositories."
exit 1
fi
- name: Install GitHub CLI
run: |
set -euo pipefail
if command -v gh >/dev/null 2>&1; then
exit 0
fi
install_dir="$RUNNER_TEMP/gh-cli"
mkdir -p "$install_dir"
release_json="$RUNNER_TEMP/gh-release.json"
archive="$RUNNER_TEMP/gh-cli.tar.gz"
curl -sSfL \
https://api.github.com/repos/cli/cli/releases/latest \
-o "$release_json"
grep -Eo 'https://[^"]+gh_[^"]+_linux_amd64\.tar\.gz' "$release_json" > "$RUNNER_TEMP/gh-assets.txt"
IFS= read -r asset_url < "$RUNNER_TEMP/gh-assets.txt" || asset_url=""
if [ -z "$asset_url" ]; then
echo "Could not resolve latest GitHub CLI linux_amd64 release asset."
exit 1
fi
curl -sSfL "$asset_url" -o "$archive"
tar -xzf "$archive" -C "$install_dir" --strip-components 1
echo "$install_dir/bin" >> "$GITHUB_PATH"
- name: Configure git authentication
run: gh auth setup-git
- name: Prepare generated AGENTS.md
run: |
{
cat <<'HEADER'
<!--
Generated from carrtech-dev/agent-instructions/AGENTS.md.
Do not edit this file directly.
Update https://github.com/carrtech-dev/agent-instructions instead.
-->
HEADER
cat AGENTS.md
} > /tmp/AGENTS.md
- name: Open sync pull requests
run: |
set -eu
while IFS= read -r repo || [ -n "$repo" ]; do
case "$repo" in
""|\#*) continue ;;
esac
echo "Syncing ${repo}"
default_branch="$(gh repo view "$repo" --json defaultBranchRef --jq '.defaultBranchRef.name')"
workdir="$(mktemp -d)"
gh repo clone "$repo" "$workdir" -- --depth 1
(
cd "$workdir"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH_NAME"
cp /tmp/AGENTS.md ./AGENTS.md
if [ -z "$(git status --porcelain -- ./AGENTS.md)" ]; then
echo "No AGENTS.md changes for ${repo}"
touch "$workdir/.no-agent-instructions-change"
exit 0
fi
git add ./AGENTS.md
git commit -m "$COMMIT_MESSAGE"
git push origin "HEAD:${BRANCH_NAME}"
)
if [ -f "$workdir/.no-agent-instructions-change" ]; then
continue
fi
gh pr create \
--repo "$repo" \
--base "$default_branch" \
--head "$BRANCH_NAME" \
--title "$PR_TITLE" \
--body "Syncs this repository's root AGENTS.md from carrtech-dev/agent-instructions."
done < sync-targets.txt
- name: Clean up runner workspace
if: always()
run: |
set +e
docker run --rm -v "$GITHUB_WORKSPACE:/ws" alpine \
chown -R "$(id -u):$(id -g)" /ws 2>/dev/null || true
find "$GITHUB_WORKSPACE" -mindepth 1 -delete 2>/dev/null || true
exit 0