From 89f4082aee34568a734dd04a7f848c8463d0cf16 Mon Sep 17 00:00:00 2001 From: bigboateng Date: Tue, 28 Jul 2026 11:58:36 +0100 Subject: [PATCH] install protected native auto-merge control --- .github/workflows/ci.yml | 52 +++++++++++++++++------------ .github/workflows/sync-upstream.yml | 10 +++++- e2e/e2e_coverage_test.go | 7 ++-- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 894cac1..300ad57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,6 @@ -# Pitot-owned control plane. +# Generated by labkit (python -m labkit gen). Do not edit by hand. +# Edit labs//publish.config.json and regenerate; drift fails `labkit doctor`. +# Install into operatorstack/pitot at .github/workflows/verify.yml (bootstrap step). name: Verify Pitot distribution on: @@ -9,40 +11,46 @@ on: permissions: contents: read +concurrency: + group: verify-pitot-${{ github.ref }} + cancel-in-progress: true + jobs: - auto-merge-sync: + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + cache: true + - run: go test ./... + - run: go build ./... + + verify-sync-provenance: if: >- github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'sync/intelligence-flow-') + needs: test runs-on: ubuntu-latest steps: - - name: Create repository automation token - id: app-token - uses: actions/create-github-app-token@v3 - with: - client-id: ${{ vars.OPERATOR_STACK_PUBLISHER_APP_CLIENT_ID || vars.BOATSTACK_APP_CLIENT_ID }} - private-key: ${{ secrets.OPERATOR_STACK_PUBLISHER_APP_PRIVATE_KEY || secrets.BOATSTACK_APP_PRIVATE_KEY }} - owner: operatorstack - repositories: pitot - permission-contents: write - permission-pull-requests: write - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Verify generated projection provenance env: - APP_SLUG: ${{ steps.app-token.outputs.app-slug }} HEAD_BRANCH: ${{ github.head_ref }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} shell: bash run: | - # Extract the 12-char commit prefix from the branch name 'sync/intelligence-flow-' - short="${HEAD_BRANCH#sync/intelligence-flow-}" - [[ "$PR_AUTHOR" == "${APP_SLUG}[bot]" ]] - [[ -n "$short" ]] - - name: Merge verified generated PR - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - PR_URL: ${{ github.event.pull_request.html_url }} - run: gh pr merge "$PR_URL" --squash + source_repo="$(jq -r '.source.repository' UPSTREAM.json)" + source_commit="$(jq -r '.source.commit' UPSTREAM.json)" + short="${source_commit:0:12}" + [[ "$PR_AUTHOR" == "operator-stack-publisher[bot]" ]] + [[ "$source_repo" == "operatorstack/intelligence-flow" ]] + [[ "$HEAD_BRANCH" == "sync/intelligence-flow-$short" ]] diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml index 737eb34..65c7828 100644 --- a/.github/workflows/sync-upstream.yml +++ b/.github/workflows/sync-upstream.yml @@ -25,7 +25,7 @@ jobs: sync: runs-on: ubuntu-latest steps: - - name: Create publisher token + - name: Create Operator Stack Publisher token id: app-token uses: actions/create-github-app-token@v3 with: @@ -109,5 +109,13 @@ jobs: --body-file "$body_file")" echo "Opened generated PR: $pr_url" else + pr_url="$existing" echo "Updated existing PR: $existing" fi + required_checks="$(gh api "repos/operatorstack/pitot/branches/main/protection/required_status_checks" --jq '(.contexts // []) + ([.checks[]?.context] // []) | unique | length')" + if [[ "$required_checks" -lt 1 ]]; then + echo "BLOCKED: main has no required status checks; refusing unsafe auto-merge." >&2 + exit 1 + fi + gh pr merge "$pr_url" --auto --squash + echo "Native auto-merge requested; branch protection owns merge eligibility." diff --git a/e2e/e2e_coverage_test.go b/e2e/e2e_coverage_test.go index 649c4e8..70fb014 100644 --- a/e2e/e2e_coverage_test.go +++ b/e2e/e2e_coverage_test.go @@ -10,9 +10,12 @@ import ( ) func TestAllAdaptersHaveE2EScripts(t *testing.T) { - // The e2e package lives in labs/15-pitot/pitot/e2e - // The test scripts live in labs/15-pitot/tests + // Monorepo: labs/15-pitot/pitot/e2e -> labs/15-pitot/tests. + // Public projection: e2e -> tests. testsDir := filepath.Join("..", "..", "tests") + if _, err := os.Stat(testsDir); os.IsNotExist(err) { + testsDir = filepath.Join("..", "tests") + } for _, host := range adapters.Supported() { t.Run(string(host), func(t *testing.T) {