Skip to content
Merged
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
78 changes: 28 additions & 50 deletions .github/workflows/inbox-steward-intake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
env:
EVENT_JSON: ${{ toJson(github.event) }}
DRY_RUN: ${{ inputs.dry_run }}
GH_TOKEN: ${{ secrets.FARM_PAT }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -101,13 +102,14 @@ jobs:
echo "validated_count=$VALIDATED" >> "$GITHUB_OUTPUT"
echo "merged_count=$MERGED" >> "$GITHUB_OUTPUT"

# Commit the report
if [ "$DRY_RUN" = "false" ]; then
# Publish the report through a PR. `inputs.dry_run` is empty on
# repository_dispatch, so only an explicit 'true' is a dry run.
if [ "$DRY_RUN" != "true" ]; then
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$REPORT_PATH"
git commit -m "inbox-steward: record from $SOURCE_REPO ($PR_COUNT PRs, $MERGED merged)" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push report"
bash scripts/open-data-pr.sh report \
"inbox-steward: record from $SOURCE_REPO ($PR_COUNT PRs, $MERGED merged)" \
"$REPORT_PATH"
else
echo "::notice::Dry run - not committing report"
fi
Expand Down Expand Up @@ -234,12 +236,10 @@ jobs:
id: update
env:
RULE_UPDATES: ${{ needs.analyze-patterns.outputs.rule_updates }}
GH_TOKEN: ${{ secrets.FARM_PAT }}
run: |
set -euo pipefail

# Load existing baseline
BASELINE_PATH=".hypatia-baseline.json"


# Create rule update file
UPDATES_DIR="data/ruleset-updates"
mkdir -p "$UPDATES_DIR"
Expand All @@ -256,39 +256,19 @@ jobs:

echo "Created rule updates: $UPDATE_FILE"

# Auto-apply critical/high priority updates
CRITICAL_UPDATES=$(echo "$RULE_UPDATES" | jq '[.[] | select(.priority == "critical" or .priority == "high")]')

if [ "$(echo "$CRITICAL_UPDATES" | jq length)" -gt 0 ]; then
echo "Applying critical/high priority updates..."

for UPDATE in $(echo "$CRITICAL_UPDATES" | jq -c '.[]'); do
UPDATE_TYPE=$(echo "$UPDATE" | jq -r '.type')
ACTION=$(echo "$UPDATE" | jq -r '.action')
REASON=$(echo "$UPDATE" | jq -r '.reason')
SUGGESTION=$(echo "$UPDATE" | jq -r '.suggestion')

echo " - $UPDATE_TYPE: $ACTION ($REASON)"

# Apply the update to baseline
# For now, append as a comment/todo - full automation needs more logic
echo " :: TODO: Apply rule update: $SUGGESTION" >> "$BASELINE_PATH"
done

# Commit updates
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$UPDATE_FILE" "$BASELINE_PATH"
git commit -m "inbox-steward: apply critical rule updates from steward reports" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push updates"
else
echo "No critical/high priority updates to apply"
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$UPDATE_FILE"
git commit -m "inbox-steward: record rule update suggestions" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push updates"
fi
# Critical/high suggestions are surfaced, not applied. This step used
# to append " :: TODO: …" text lines to .hypatia-baseline.json,
# which corrupts the JSON the Governance baseline gate reads. The
# suggestions live only in $UPDATE_FILE (`applied: false`).
echo "$RULE_UPDATES" \
| jq -r '.[] | select(.priority == "critical" or .priority == "high")
| "::notice title=Rule update suggested (\(.priority))::\(.type): \(.action) (\(.reason)) — \(.suggestion)"'

git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
bash scripts/open-data-pr.sh rule-updates \
"inbox-steward: record rule update suggestions" \
"$UPDATE_FILE"

# Job 4: Dispatch to .git-private-farm for fleet-wide application
dispatch-to-farm:
Expand Down Expand Up @@ -333,14 +313,12 @@ jobs:

echo "Dispatching to .git-private-farm: $(echo "$PAYLOAD" | jq -c '.')"

# Send to .git-private-farm
if gh api -X POST \
"/repos/hyperpolymath/.git-private-farm/dispatches" \
--input - <<<"$PAYLOAD" >/dev/null 2>&1; then
echo "✅ Successfully dispatched to .git-private-farm"
else
echo "::warning::Failed to dispatch to .git-private-farm"
fi
# Send to .git-private-farm. A refused dispatch fails the job; it
# used to be swallowed into a warning with stderr discarded.
gh api -X POST \
"/repos/hyperpolymath/.git-private-farm/dispatches" \
--input - <<<"$PAYLOAD" >/dev/null
echo "✅ Successfully dispatched to .git-private-farm"

# Job 5: Summary
summary:
Expand Down
45 changes: 45 additions & 0 deletions scripts/open-data-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# open-data-pr.sh — land machine-written data files on main through a PR
#
# Usage: open-data-pr.sh <branch-suffix> <title> <path>...
#
# Commits <path>... on a new branch `inbox-steward/<run_id>-<suffix>`, pushes
# it, opens a PR against main and queues a squash auto-merge. Used by
# inbox-steward-intake.yml instead of `git push origin HEAD` to main, which
# bypassed review and signing and was masked so a refusal stayed green.
#
# Needs: GH_TOKEN (a credential with Contents and Pull requests write on this
# repository), GITHUB_RUN_ID, GITHUB_REPOSITORY, and a checkout whose `origin`
# authenticates with the same credential. Every failure exits non-zero.
set -euo pipefail

if [ "$#" -lt 3 ]; then
echo "usage: $0 <branch-suffix> <title> <path>..." >&2
exit 2
fi

suffix="$1"
title="$2"
shift 2

git add -- "$@"
if git diff --cached --quiet; then
echo "No changes under $* — nothing to publish."
exit 0
fi

branch="inbox-steward/${GITHUB_RUN_ID}-${suffix}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make publication branches unique across reruns

If an attempt fails after pushing this branch but before completing the PR/merge operation, rerunning the same workflow uses the unchanged GITHUB_RUN_ID and reconstructs the same branch name. The new commit is created independently from main, so the push is normally rejected as non-fast-forward (or PR creation collides with the existing PR), preventing the rerun from recovering from the original transient failure. Include GITHUB_RUN_ATTEMPT or explicitly resume/clean up the existing branch.

Useful? React with 👍 / 👎.

git switch -c "$branch"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Create the data branch from the PR base

When a maintainer starts the workflow_dispatch from a non-main branch or tag with dry_run false, actions/checkout checks out that selected ref and this command creates the publication branch directly from it. The resulting PR targets main, so it includes every commit unique to the selected ref in addition to the generated data file. Create the branch from the fetched origin/main ref, or restrict writable dispatches to main, before committing the generated path.

Useful? React with 👍 / 👎.

git commit -m "$title"
git push origin "HEAD:refs/heads/${branch}"

pr_url="$(gh pr create --repo "$GITHUB_REPOSITORY" --base main --head "$branch" \
--title "$title" \
--body "Machine-written by inbox-steward-intake.yml, run ${GITHUB_RUN_ID}. Data files only.")"
echo "opened ${pr_url}"

# --auto queues the merge until the base-branch policy allows it; a bare
# merge right after creation is refused before the policy settles.
gh pr merge "${pr_url##*/}" --repo "$GITHUB_REPOSITORY" --squash --auto --delete-branch

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Wait for the queued PR to actually merge

When required checks are pending, gh pr merge --help states that --auto only enables a later merge after requirements are met, so a zero exit here does not mean the data reached main. The helper therefore returns success immediately, allowing dispatch-to-farm in .github/workflows/inbox-steward-intake.yml to publish paths that do not exist on main; if CI later fails, the intake run still remains green. Poll the PR state and fail unless it reaches MERGED, as the repository's estate-rescan.yml publisher already does.

Useful? React with 👍 / 👎.

echo "auto-merge queued for ${pr_url}"
Loading