Keep projects up to date automatically¶
A project stays on its release until someone runs agd update. A scheduled GitHub Actions workflow can do it for you: each week it checks for a newer release, runs the update, and opens a pull request with the changes.
The workflow¶
agd keeps its own repository's setup up to date with this file, so it is the one in use. Copy it to .github/workflows/agd-update.yml in your project:
# Keeps this repository's agentic setup up to date: weekly, it runs agd update and opens a pull request
# with the changes. docs/guides/automatic-updates.md shows this file; any project can copy it as is.
name: Update the agentic setup
on:
schedule:
- cron: "0 7 * * 1" # Mondays
workflow_dispatch:
permissions:
contents: write
pull-requests: write
# bash -eo pipefail instead of the default bash -e, so a failing agd update isn't hidden by tee.
defaults:
run:
shell: bash
jobs:
update:
runs-on: ubuntu-latest
env:
# A pinned agd release, and the SHA-256 of its agd file from the release's SHA256SUMS.
AGD_VERSION: 0.3.0
AGD_SHA256: 0a83043c533faea476e9f454eadf7ed693cf31296748f41540ab6321fc24978f
BRANCH: agd-update
steps:
- uses: actions/checkout@v5
- name: Install agd
run: |
mkdir -p "$HOME/.local/bin"
curl -fsSLo "$HOME/.local/bin/agd" "https://github.com/Zejnilovic/agd/releases/download/v$AGD_VERSION/agd"
echo "$AGD_SHA256 $HOME/.local/bin/agd" | sha256sum -c -
chmod +x "$HOME/.local/bin/agd"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Check for a newer setup
id: check
run: |
code=0
agd status --check || code=$?
[ "$code" -le 1 ] || exit "$code"
echo "due=$code" >> "$GITHUB_OUTPUT"
- name: Update and open a pull request
if: steps.check.outputs.due == '1'
env:
GH_TOKEN: ${{ github.token }}
run: |
agd update | tee "$RUNNER_TEMP/update.txt"
# Only files this project edited are due, and the update leaves those alone.
[ -n "$(git status --porcelain)" ] || exit 0
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git switch -c "$BRANCH"
git add -A
git commit -q -m "Update the agentic setup" -m "$(cat "$RUNNER_TEMP/update.txt")"
git push -q --force origin "$BRANCH"
{
echo 'The weekly `agd update` changed these files. Read the changes before you merge: they are instructions for agents.'
echo
echo '```text'
cat "$RUNNER_TEMP/update.txt"
echo '```'
echo
echo 'An `edited` line is a file this project changed, which the update left alone. Settle it after you merge, with `agd diff`, then `agd merge` or `agd reset`: the next run replaces this branch.'
} > "$RUNNER_TEMP/body.md"
pr=$(gh pr list --head "$BRANCH" --state open --json number --jq '.[0].number')
if [ -n "$pr" ]; then
gh pr edit "$pr" --body-file "$RUNNER_TEMP/body.md"
else
gh pr create --head "$BRANCH" --title "Update the agentic setup" --body-file "$RUNNER_TEMP/body.md"
fi
It runs on Mondays, and whenever you start it from the Actions tab (Run workflow). Each run:
- Installs a pinned agd release and checks the file against the checksum from the release's
SHA256SUMS, so a changed download fails the run. - Runs
agd status --check. Exit 0 means nothing is due, and the run ends there. Any exit above 1 is an error, which fails the run. - On exit 1, runs
agd update, commits the result to theagd-updatebranch, and opens a pull request, or updates the body of the one that is open. The body is whatagd updateprinted.
To move to a newer agd, change AGD_VERSION and AGD_SHA256: the checksum is the agd line of that release's SHA256SUMS.
Permissions¶
The job needs contents: write to push the branch, and pull-requests: write to open the pull request; the workflow asks for both. GitHub still forbids workflows to open pull requests until you allow it. The branch is pushed, then the run fails with:
pull request create failed: GraphQL: GitHub Actions is not permitted to create or approve pull requests (createPullRequest)
In Settings → Actions → General, under "Workflow permissions", turn on Allow GitHub Actions to create and approve pull requests, and run the workflow again. In an organization, the organization's settings may have to allow it first.
For a private source, give git a token that can read it before the update step, as the FAQ shows.
Why a pull request, not a push¶
The files an update changes are instructions for your agents: what they do, which tools they may run, which model they use. Someone should read a new release of them before every agent in the project follows it, as with a dependency update. The pull request is that review, and your checks run on it.
Checks on the pull request
GitHub doesn't start workflows for a pull request that a workflow opened with its own token. To run your checks on it, close and reopen the pull request, or give the update step a token of a GitHub App or a person as GH_TOKEN, and push with it.
What the pull request shows¶
The body lists every file, as agd update printed it. Shortened, for this repository's update to agentic-defaults 0.5.1 with one skill edited:
notes https://github.com/Zejnilovic/agentic-defaults/releases/tag/v0.5.0
notes https://github.com/Zejnilovic/agentic-defaults/releases/tag/v0.5.1
pack aws is new in agentic-defaults 0.5.1: agd add aws installs it
updated .claude/agents/developer.md
updated AGENTS.md
added .claude/skills/session-retro/SKILL.md
edited .claude/skills/implementation/SKILL.md: left alone, and a newer version is available (see agd diff .claude/skills/implementation/SKILL.md, then agd merge or agd reset it)
agentic-defaults is at 0.5.1: 8 updated, 2 added, 0 removed.
Read the release notes it links: a release can ask for manual steps. New packs aren't installed; add one with agd add <pack> if you want it.
An edited line is a file your project changed. The update leaves it alone, so the pull request doesn't touch it: that file is the reviewer's to settle. After you merge, run agd diff <path>, then agd merge <path> or agd reset <path>, as Make files your own shows. Settle it on your main branch rather than on agd-update, since the next run replaces that branch.
Until you settle it, agd status --check keeps reporting the update as due. When such files are all that is due, the update changes nothing, and the run ends without a pull request.