Skip to content

Merge Data Branch

Merge Data Branch #46

Workflow file for this run

---
name: Merge Data Branch
on:
repository_dispatch:
types:
- promote-data
schedule:
- cron: '0 22 * * 0' # Every Sunday at 22:00 UTC
workflow_dispatch:
concurrency:
group: merge-data-${{ github.event_name == 'repository_dispatch' && 'dispatch' || 'manual' }}
cancel-in-progress: ${{ github.event_name == 'repository_dispatch' }}
permissions:
contents: read
# The future `fro-bot/dashboard` broker will dispatch the fast path after a successful data commit; the weekly cron is the backstop.
# It must use the App token or `FRO_BOT_PAT`: `GITHUB_TOKEN`-created events, including `repository_dispatch`, return 204 but do not start workflow runs.
jobs:
merge-data:
name: Merge data into main
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- id: get-workflow-app-token
name: Get Workflow Access Token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.APPLICATION_ID }}
private-key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
- name: ⤵ Checkout Branch
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: main # load-bearing for the privacy gate's grandfather comparison; do not remove
fetch-depth: 0 # full history needed for three-dot diff in promotion privacy check
- name: 📦 Setup
uses: ./.github/actions/setup
# Two checkouts: scripts live on main, the wiki/metadata being promoted live on data.
# The privacy check below runs from the data subtree to gate the actual merge content.
- name: ⤵ Fetch data branch for privacy check
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: data
path: data-branch-check
# Privacy gate: blocks promotion if a private repo's wiki page would leak onto main.
# Design: delta-based public-allowlist inversion — no GraphQL needed.
# - data's own repos.yaml is authoritative (data branch is the writer)
# - publicSlugs built from entries with explicit private===false via computeRepoSlug
# - pages already on main (default checkout = main) are grandfathered to avoid
# re-flagging verifiably-public repos that lack an explicit private===false field
# (e.g. marcusrbrown/copiloting: onboarding_status=lost-access, absent private)
# - dead/node-null orphans are tolerated: if already on main → grandfathered;
# if genuinely new → correctly flagged without any GraphQL call
- name: 🔒 Block private wiki pages
env:
GRANDFATHER_WIKI_REPOS_DIR: ../knowledge/wiki/repos
working-directory: data-branch-check
run: node ../scripts/check-wiki-private-presence.ts
# Promotion privacy gate: blocks merge if a private repo name appears in the data→main diff.
# Design: three-dot diff (origin/main...origin/data) against private node_ids from data's
# repos.yaml — requires full history (fetch-depth: 0 above) and origin/data ref (fetched
# below). The fetch runs under the default checkout GITHUB_TOKEN (sufficient to reach
# origin/data); the broad-scope FRO_BOT_POLL_PAT is confined to the node step that resolves
# private names. Splitting the steps keeps FRO_BOT_POLL_PAT out of every git subprocess —
# the env-stripping in runPromotionCli enforces the same property for the diff git call.
- name: 🔒 Fetch data ref for promotion diff
run: git fetch --no-tags --prune origin data
- name: 🔒 Block private repo names in promotion diff
env:
FRO_BOT_POLL_PAT: ${{ secrets.FRO_BOT_POLL_PAT }}
PROMOTION_REPOS_YAML_PATH: data-branch-check/metadata/repos.yaml
run: node scripts/check-private-leak.ts --promotion
- name: 🔀 Open data merge PR
env:
GITHUB_TOKEN: ${{ steps.get-workflow-app-token.outputs.token }}
run: node scripts/merge-data-pr.ts