Skip to content

Route Sync

Route Sync #3

Workflow file for this run

name: Route Sync
# Opens a PR when the backend's canonical v2 route manifest drifts from the
# vendored copy; that PR fails test_route_coverage until the matching SDK
# methods + `# v2:covers` comments are added.
#
# Needs a cross-repo credential (the default GITHUB_TOKEN can't read the private
# backend repo, and PRs it opens don't trigger CI). Use EITHER:
# - a fine-grained PAT (owner TextQLLabs, repos demo2 + textql-python,
# Contents: read/write, Pull requests: read/write) as secret
# BACKEND_REPO_TOKEN; or
# - a GitHub App (var SYNC_APP_ID + secret SYNC_APP_PRIVATE_KEY) installed on
# both repos with the same permissions.
# The App is preferred (no expiry); the job no-ops until one is configured.
on:
schedule:
- cron: "0 12 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
env:
BACKEND_REPO_NAME: ${{ vars.BACKEND_REPO_NAME || 'demo2' }}
MANIFEST_PATH: ${{ vars.BACKEND_MANIFEST_PATH || 'compute/pkg/platform/v2/routes.manifest.json' }}
# Track the PROD contract: the SDK defaults to app.textql.com, and demo2's
# `main` is staging — prod is the `release` branch. Tracking `main` would
# sync the SDK ahead of what prod serves.
MANIFEST_REF: ${{ vars.BACKEND_MANIFEST_REF || 'release' }}
steps:
- uses: actions/checkout@v4
- name: Mint App token
id: app-token
if: ${{ vars.SYNC_APP_ID != '' }}
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.SYNC_APP_ID }}
private-key: ${{ secrets.SYNC_APP_PRIVATE_KEY }}
repositories: |
${{ vars.BACKEND_REPO_NAME || 'demo2' }}
${{ github.event.repository.name }}
- name: Resolve token
id: token
env:
APP_TOKEN: ${{ steps.app-token.outputs.token }}
PAT: ${{ secrets.BACKEND_REPO_TOKEN }}
run: |
tok="${APP_TOKEN:-$PAT}"
if [ -z "$tok" ]; then echo "has_token=false" >> "$GITHUB_OUTPUT"; else echo "has_token=true" >> "$GITHUB_OUTPUT"; fi
echo "::add-mask::$tok"
echo "value=$tok" >> "$GITHUB_OUTPUT"
- name: Fetch upstream manifest
id: fetch
if: ${{ steps.token.outputs.has_token == 'true' }}
env:
GH_TOKEN: ${{ steps.token.outputs.value }}
run: |
set -euo pipefail
if ! gh api "repos/${{ github.repository_owner }}/${BACKEND_REPO_NAME}/contents/${MANIFEST_PATH}?ref=${MANIFEST_REF}" \
-H "Accept: application/vnd.github.raw" > upstream.json 2> fetch_err; then
if grep -qi "not found" fetch_err; then
echo "manifest not on '${MANIFEST_REF}' yet (or path moved); skipping"
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
cat fetch_err >&2
exit 1
fi
changed=$(python3 -c "import json; a=set(json.load(open('upstream.json'))); b=set(json.load(open('tests/routes.manifest.json'))); print('true' if a!=b else 'false')")
if [ "$changed" = "true" ]; then cp upstream.json tests/routes.manifest.json; fi
echo "changed=$changed" >> "$GITHUB_OUTPUT"
- name: Open PR
if: ${{ steps.fetch.outputs.changed == 'true' }}
uses: peter-evans/create-pull-request@v6
with:
token: ${{ steps.token.outputs.value }}
branch: route-sync
add-paths: tests/routes.manifest.json
commit-message: "chore: sync v2 route manifest from backend"
title: "chore: sync v2 route manifest from backend"
body: |
The backend `/v2` route set changed. Add/rename the matching SDK
methods and their `# v2:covers` comments until `test_route_coverage`
passes.