Skip to content

Open Downstream QPK Pin PRs #97

Open Downstream QPK Pin PRs

Open Downstream QPK Pin PRs #97

name: Open Downstream QPK Pin PRs
on:
push:
branches: [ main ]
paths:
- "QPK_PIN"
schedule:
- cron: "17 * * * *"
workflow_dispatch:
inputs:
phase:
description: "Staged dependency rollout phase"
required: true
default: auto
type: choice
options:
- auto
- strategies
- consumers
permissions:
contents: read
jobs:
open-prs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.1.0
with:
python-version: "3.11"
- name: Install tooling
run: |
set -euo pipefail
python -m pip install --upgrade pip uv
type -p gh >/dev/null || (type -p apt-get >/dev/null && sudo apt-get update -qq && sudo apt-get install -y -qq gh)
- name: Open downstream pin sync PRs
id: sync
env:
QSL_REPO_SYNC_TOKEN: ${{ secrets.QSL_REPO_SYNC_TOKEN }}
QSL_PIN_PHASE: ${{ github.event_name == 'workflow_dispatch' && inputs.phase || 'auto' }}
run: |
set -euo pipefail
if [ -z "${QSL_REPO_SYNC_TOKEN:-}" ]; then
echo "missing_token=true" >> "$GITHUB_OUTPUT"
exit 0
fi
python3 scripts/open_downstream_qpk_pin_prs.py --phase "$QSL_PIN_PHASE" | tee downstream-prs.txt
- name: Create coherent aggregate bundle PR
if: steps.sync.outputs.missing_token != 'true'
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.8
with:
token: ${{ secrets.QSL_REPO_SYNC_TOKEN }}
commit-message: "chore(deps): reconcile coherent QSL pin bundle"
title: "chore(deps): reconcile coherent QSL pin bundle"
body: |
Reconciles the aggregate QSL dependency bundle only after every strategy
package on `main` pins the staged `QPK_PIN`.
The consumer phase validates each broker/QMT dependency closure before
opening its downstream PR.
branch: auto/qsl-pin-bundle
delete-branch: true
base: main
add-paths: |
qsl-pins.txt
constraints.txt
- name: Queue verified strategy pin PRs
if: steps.sync.outputs.missing_token != 'true'
env:
QSL_REPO_SYNC_TOKEN: ${{ secrets.QSL_REPO_SYNC_TOKEN }}
run: |
set -euo pipefail
qpk_sha=$(tr -d '[:space:]' < QPK_PIN)
python3 scripts/merge_verified_strategy_qpk_pin_prs.py --qpk-sha "$qpk_sha" --close-superseded
- name: Report consumer QPK pin PR hygiene
if: steps.sync.outputs.missing_token != 'true'
env:
QSL_REPO_SYNC_TOKEN: ${{ secrets.QSL_REPO_SYNC_TOKEN }}
run: |
set -euo pipefail
qpk_sha=$(tr -d '[:space:]' < QPK_PIN)
python3 scripts/report_consumer_qpk_pin_prs.py --qpk-sha "$qpk_sha" >> "$GITHUB_STEP_SUMMARY"
- name: Summarize missing token
if: steps.sync.outputs.missing_token == 'true'
run: |
cat >> "$GITHUB_STEP_SUMMARY" <<'MD'
## Downstream QPK pin PRs were not opened
Missing repository secret: `QSL_REPO_SYNC_TOKEN` on **QuantPlatformKit**.
Org-level secrets are **not** injected reliably into this public repo on GitHub Free.
Configure a **repository secret** instead (see `docs/qpk_repo_sync_auth.zh-CN.md`).
Quick bootstrap (org admin, local `gh` login):
```bash
gh secret set QSL_REPO_SYNC_TOKEN --repo QuantStrategyLab/QuantPlatformKit --body "$(gh auth token)"
```
Production: use a dedicated fine-grained PAT (`contents:write`, `pull_requests:write`, `metadata:read`)
scoped to QuantStrategyLab downstream repos.
MD
- name: Summarize opened PRs
if: steps.sync.outputs.missing_token != 'true'
run: |
cat >> "$GITHUB_STEP_SUMMARY" <<'MD'
## Downstream QPK pin PR results
MD
cat downstream-prs.txt >> "$GITHUB_STEP_SUMMARY"