feat(ci): add upstream-sync workflow with deterministic conflict rules#25
Merged
Conversation
PR B of the flex-CI-setup plan. Adds .github/workflows/upstream-sync.yml
and rewrites README_FLEXION.md Option A to match the actually-shipped
behavior (no Bedrock).
The workflow:
- workflow_dispatch only, inputs: dry_run (default true) and target_ref
(default refs/heads/main → upstream/main)
- Detects drift via `git rev-list flex..upstream/main`
- On dry_run, reports drift count and exits
- On real run, creates upstream-sync/YYYYMMDD-HHMMSS, rebases, applies
per-file rules:
* *.png|*.ico|*.wasm → --ours
* package-lock.json|uv.lock → --theirs
* functions/**|static/static/providers/**|README_FLEXION.md → --ours
* everything else → conflict markers stay in the committed content
- Accumulates a conflict-resolution log as markdown
- Opens a PR (draft if manual review is needed, ready otherwise) with
the log + HITL checklist + list of files containing markers
Uses SYNC_PAT for both checkout and push because GITHUB_TOKEN can't push
branches that touch .github/workflows/.
No Bedrock or other LLM dependencies. Future upgrade path: insert an
LLM-assisted resolver as a step BEFORE the "leave markers" fallback,
without changing surrounding plumbing.
Replaces the "rebase against upstream/main HEAD" model with a daily
schedule that watches for new upstream v*.*.* release tags. On no-new-
release days, the workflow exits cleanly without opening a PR.
Why: upstream's main branch evolves with every commit, but flex tracks
releases (v0.9.5, etc.). Syncing against main HEAD would create churn
from every upstream commit; syncing against release tags matches how the
ECR tagging and CDK pinning already work.
Changes:
- Triggers: on.schedule (daily 09:00 UTC) + on.workflow_dispatch
- workflow_dispatch inputs replaced:
- dry_run (boolean) → removed
- target_ref (string, default refs/heads/main) → removed
- target_tag (string, optional) → new; blank = auto-detect latest v*.*.*
- force (boolean, default false) → new; bypass "already on target" check
- Detection:
- target tag: explicit input, or `git tag -l 'v[0-9]*.[0-9]*.[0-9]*'
--sort=-version:refname | head -n 1` (pre-releases excluded)
- current base: `git describe --tags --abbrev=0 flex`
- Safety: refuses to sync backward (target older than base) without force
- Concurrency group "upstream-sync", no cancel-in-progress
- Throwaway branch name now includes the target tag for traceability
- PR body now references "Publish flex image to ECR" as the followup step
Also rewrites README_FLEXION.md Option A to describe the new model.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR B of the flex-CI-setup plan. Adds the upstream-sync GitHub Actions workflow and rewrites README_FLEXION.md's Option A to match what's shipped.
What this does
.github/workflows/upstream-sync.ymlruns daily on a schedule and watches for new upstreamv*.*.*release tags. On no-new-release days, it exits cleanly.When it sees a new tag:
v*.*.*, or an explicittarget_taginput on manual runs)git describe --tags --abbrev=0 flexforce: true)force: trueupstream-sync/<target>-YYYYMMDD-HHMMSS, rebases onto the target tag with deterministic per-file rules:*.png,*.ico,*.wasm) →--ourspackage-lock.json,uv.lock) →--theirsfunctions/,static/static/providers/,README_FLEXION.md) →--oursWhy a tag-driven schedule (vs HEAD-driven manual dispatch)
Upstream's main branch evolves with every commit, but
flextracks releases (v0.9.5, etc.) and the ECR tagging + CDK pinning already work this way. Syncing against main HEAD would create churn from every upstream commit; syncing against release tags matches how everything else is versioned.Triggers
schedule:—0 9 * * *(daily 09:00 UTC)workflow_dispatch:— manual escape hatch with optionaltarget_tagandforceinputsConcurrency
group: upstream-sync,cancel-in-progress: false— only one sync runs at a time, no in-flight cancellation.Required prerequisites (already complete)
SYNC_PATrepo secret — fine-grained PAT, Contents/Pull-requests/Workflows write, SSO-authorized forflexionflexis the default branch — workflows must register on the default branch to be dispatchable and scheduledTest plan
After merge:
gh workflow run upstream-sync.yml. Expect: workflow detectsflexis already onv0.9.5, emits the "Up to date" notice, and exits.v0.9.6.v0.9.6+, the scheduled run opens a PR. Verify the conflict-resolution log is sensible and the rebase target is correct.Files changed
.github/workflows/upstream-sync.yml— newREADME_FLEXION.md— Option A rewritten for the schedule + tag model