Fix the weekly agd update: signed commits, agd 0.5.1, agentic-defaults 0.5.4 steps

Open
#89 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
git, github-actions, python
Domain
devops, release

Research direction

Start with .github/workflows/agd-update.yml and compare its checkout and commit steps with the jacoco-report reference linked in the issue; then review AGENTS.md and .agd.lock. Follow the issue’s staged workflow run and verification steps, keeping the existing update PR open. Done when the run from master is green and verified, the temporary branch is gone, the update PR merges agentic-defaults 0.5.4, and AGENTS.md has the Company knowledge heading.

Written by the indexing model from the issue text.

Description

infrastructure

Status (2026-11-08): not started. The reference implementation is done and tested in MoranaApps/jacoco-report (#315, #319, update #317 merged at agentic-defaults 0.5.4).

The task

The weekly Update the agentic setup workflow works here, because the signature rule covers only master. PR #75 (agentic-defaults 0.5.3) has been open since 2026-11-02. Make the workflow the same as in the other living-doc repositories, where the push fails, and move to agentic-defaults 0.5.4.

Now: .agd.lock at agentic-defaults 0.5.2 (latest 0.5.4), and the workflow pins agd 0.3.0 (latest 0.5.1).

Already in place: "Allow GitHub Actions to create and approve pull requests" is on in this repository (checked 2026-11-08). In MoranaApps it had to be allowed at the organization level first.

Steps

A. One PR with the fix (steps 1–4). Copy the commit block and the checkout setting from the jacoco-report workflow, and keep this repository's own issue, branch, title and PR-body logic.

  1. Signed commits: not needed for the push here, but apply the same API commit and persist-credentials: false (below, headline="#$issue: $TITLE"), so one copy of the workflow fits every living-doc repository and keeps working if the all-branches rule arrives.
  2. agd 0.5.1: AGD_VERSION: 0.5.1 and AGD_SHA256: 6c361845bb96b89af8193c57c0742cfabd96c773ae8b950ca3ea3128b5771457 (the agd line of the release's SHA256SUMS).
  3. One workflow for all repositories: take the two changes living-doc-collector-gh has: the issue search filter (--search "\"$TITLE\" in:title") and the PR-body note about Approve workflows to run. Also move contents/issues/pull-requests: write from the workflow to the update job, and leave contents: read at the workflow level, as the other repositories do.
  4. Company knowledge: add ### Company knowledge under ## This project in AGENTS.md (0.5.4). Updates keep an existing "This project", so the heading arrives only by hand. Keep the kit's comment, or add one-line pointers. Doing it in this PR saves one later.

B. Test before merge.

  1. gh workflow run agd-update.yml --ref <fix branch>. It makes a Verified commit on chore/74-agd-update and refreshes PR #75 to agentic-defaults 0.5.4. PR #75 must stay open. It also shows the fix's own changes for now, because the run starts from the fix branch.
  2. Check: gh api repos/AbsaOSS/living-doc/commits/chore/74-agd-update -q .commit.verification.verified prints true, and gh api repos/AbsaOSS/living-doc/git/matching-refs/heads/chore/74-agd-update-tmp -q length prints 0.

C. Merge and update.

  1. Merge the fix, then Run workflow again from master. The update PR stays open, and now shows only kit files, .agd.lock and AGENTS.md.
  2. On the update PR, click Approve workflows to run: GitHub holds the checks of a PR that GitHub Actions opened. Review, reading the diffs of .claude/skills/context-md/check.sh and .claude/skills/session-retro/stats.sh in full, since they run. Merge.

D. Remaining items from the release notes (0.5.3, 0.5.4):

  • 0.5.3: a CI job running context-md/check.sh on a shallow checkout now fails. This repository has no such job, so there is nothing to do.
  • Copilot CLI doesn't recognize the agents' haiku and sonnet. Keep those lines for Claude Code. Copilot CLI users set subagents.agents.<name>.model in their own ~/.copilot/settings.json.
  • Decide whether to run agd add copilot-hook, which adds an end-of-turn CONTEXT.md check for Copilot agent mode in VS Code. Worth it if the team uses that mode here.
Done when
  • The run from master is green, its commit shows Verified, and no chore/74-agd-update-tmp-* branch is left.
  • The update PR stayed open through the runs.
  • .agd.lock on master is at agentic-defaults 0.5.4, agd status --check exits 0, and the merged PR closed #74.
  • AGENTS.md has the Company knowledge heading.
  • The PR diff shows no file mode changes. The API commit carries no modes. In jacoco-report the kit's scripts were 100644 already, so expect none.
Lessons from jacoco-report
  • Never reset the update branch to master before committing. For a moment the branch has no commits, and GitHub closes the open update PR. The run from master closed jacoco-report#316 and opened #317 (fixed in #319). The snippet commits on a temporary branch, then moves the update branch in one step.
  • Contents never go through command-line arguments. Linux limits one argument to 128 KiB. The 0.5.4 update used about 109 KB of it, and a whole kit is about 151 KB.
  • Verified doesn't mean the content is trusted. The signature only shows that GitHub made the commit with this repository's token. Review the update PR as you would a dependency update.
Signed commit through the API

Reference implementation, tested and green: MoranaApps/jacoco-report agd-update.yml (#315, #319). Its commit on agd-update shows Verified, and an open update PR stays open across runs.

Checkout: nothing pushes with git any more, so don't keep the token in .git/config:

- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
  with:
    # Nothing pushes with git: the commit goes through the API with GH_TOKEN.
    persist-credentials: false

Update step: replace git config / git switch -c / git add -A / git commit / git push --force with the lines below. GitHub signs a commit made with the GraphQL createCommitOnBranch mutation, so it passes the required_signatures rule. $branch is the branch the step already computes. Set headline to the commit title the step used before, as step 1 says.

# Every file the update added, changed or deleted, as JSON files: Linux limits one command-line
# argument to 128 KiB, and a whole kit is larger, so the contents never go through arguments. They're
# built before the branch moves, so a failure here leaves the branch and its pull request as they were.
git add -A
# shellcheck disable=SC2016 # sh -c and jq expand these, not this shell
git diff --cached --no-renames --name-only --diff-filter=AM -z \
  | xargs -0 -r -I{} sh -c 'base64 -w0 < "$1" | tr -d "\n" | jq -Rs --arg p "$1" "{path:\$p,contents:.}"' _ {} \
  | jq -s . > "$RUNNER_TEMP/additions.json"
# shellcheck disable=SC2016 # jq expands $p, not this shell
git diff --cached --no-renames --name-only --diff-filter=D -z \
  | xargs -0 -r -I{} jq -n --arg p {} '{path:$p}' \
  | jq -s . > "$RUNNER_TEMP/deletions.json"
# One commit through the API, which GitHub signs, made on a temporary branch from the checked-out
# commit. $branch then moves to it in one step, as the force push did: resetting $branch to the
# checked-out commit first would leave it with no commits for a moment, and GitHub closes an open
# pull request whose branch has none. The trap deletes the temporary branch, also after a failure.
base=$(git rev-parse HEAD)
tmp="$branch-tmp-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
gh api -X POST "repos/$GITHUB_REPOSITORY/git/refs" -f ref="refs/heads/$tmp" -f sha="$base" >/dev/null
trap 'gh api -X DELETE "repos/$GITHUB_REPOSITORY/git/refs/heads/$tmp" >/dev/null 2>&1 || true' EXIT
commit=$(jq -n --arg repo "$GITHUB_REPOSITORY" --arg branch "$tmp" --arg oid "$base" \
  --arg headline "$headline" --rawfile body "$RUNNER_TEMP/update.txt" \
  --slurpfile add "$RUNNER_TEMP/additions.json" --slurpfile del "$RUNNER_TEMP/deletions.json" \
  '{query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { oid } } }",
    variables: {input: {branch: {repositoryNameWithOwner: $repo, branchName: $branch},
      expectedHeadOid: $oid, message: {headline: $headline, body: $body},
      fileChanges: {additions: $add[0], deletions: $del[0]}}}}' \
  | gh api graphql --input - --jq '.data.createCommitOnBranch.commit.oid')
[ -n "$commit" ] || { echo "::error::The API returned no commit."; exit 1; }
if gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/$branch" >/dev/null 2>&1; then
  gh api -X PATCH "repos/$GITHUB_REPOSITORY/git/refs/heads/$branch" -f sha="$commit" -F force=true >/dev/null
else
  gh api -X POST "repos/$GITHUB_REPOSITORY/git/refs" -f ref="refs/heads/$branch" -f sha="$commit" >/dev/null
fi

The job's GH_TOKEN: ${{ github.token }} with contents: write is enough.

Not chosen: excluding the update branch from the all-branches signature ruleset. It would work, but it weakens a security rule, and the API commit needs no exception.

Related

The same fix in every repository that uses agd, so one workflow file fits all:

Order: living-doc-collector-gh next, since its workflow is the AbsaOSS baseline. Then copy its result to the other five.

Dominant language
Python
Stars
0
Forks
0
Avg merge
6h 14m
Merged PRs (30d)
27

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from AbsaOSS/living-doc

All issues in AbsaOSS/living-doc

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.