From 17a99a0e20d00d35f2c0eb5e235e54b50ccdffab Mon Sep 17 00:00:00 2001 From: DhanushSantosh Date: Wed, 18 Feb 2026 11:16:06 +0530 Subject: [PATCH 1/3] fix: restrict Linux native bindings install to Linux runners only The setup-project action was force-installing Linux-specific npm binaries (@rollup/rollup-linux-x64-gnu, @tailwindcss/oxide-linux-x64-gnu) on ALL platforms including macOS and Windows. This overwrote the correct platform-native binaries, causing Vite builds to fail on those runners, which prevented any release assets from being uploaded. Also removes the redundant `draft == false` condition from the upload job (already guaranteed by `types: [published]` trigger) and adds an explicit checkout step to the upload job for correctness. Co-Authored-By: Claude Sonnet 4.5 --- .github/actions/setup-project/action.yml | 1 + .github/workflows/release.yml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-project/action.yml b/.github/actions/setup-project/action.yml index 0fcd1e4f..5fac3a8f 100644 --- a/.github/actions/setup-project/action.yml +++ b/.github/actions/setup-project/action.yml @@ -45,6 +45,7 @@ runs: run: npm install --ignore-scripts --force - name: Install Linux native bindings + if: runner.os == 'Linux' shell: bash # Workaround for npm optional dependencies bug (npm/cli#4828) # Explicitly install Linux bindings needed for build tools diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d7ce2b82..f4fe01f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,9 +95,11 @@ jobs: upload: needs: build runs-on: ubuntu-latest - if: github.event.release.draft == false steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Download macOS artifacts uses: actions/download-artifact@v4 with: From 6b9946df952521ec96dd3f2625cb4aebd0878fd8 Mon Sep 17 00:00:00 2001 From: DhanushSantosh Date: Wed, 18 Feb 2026 11:48:33 +0530 Subject: [PATCH 2/3] chore: restore check-sync.sh and DEVELOPMENT_WORKFLOW.md These files were accidentally dropped from patchcraft. Restoring from upstream/main to preserve the sync workflow tooling and documentation. Co-Authored-By: Claude Sonnet 4.5 --- DEVELOPMENT_WORKFLOW.md | 253 ++++++++++++++++++++++++++++++++++++++++ check-sync.sh | 215 ++++++++++++++++++++++++++++++++++ 2 files changed, 468 insertions(+) create mode 100644 DEVELOPMENT_WORKFLOW.md create mode 100755 check-sync.sh diff --git a/DEVELOPMENT_WORKFLOW.md b/DEVELOPMENT_WORKFLOW.md new file mode 100644 index 00000000..0ce198ce --- /dev/null +++ b/DEVELOPMENT_WORKFLOW.md @@ -0,0 +1,253 @@ +# Development Workflow + +This document defines the standard workflow for keeping a branch in sync with the upstream +release candidate (RC) and for shipping feature work. It is paired with `check-sync.sh`. + +## Quick Decision Rule + +1. Ask the user to select a workflow: + - **Sync Workflow** → you are maintaining the current RC branch with fixes/improvements + and will push the same fixes to both origin and upstream RC when you have local + commits to publish. + - **PR Workflow** → you are starting new feature work on a new branch; upstream updates + happen via PR only. +2. After the user selects, run: + ```bash + ./check-sync.sh + ``` +3. Use the status output to confirm alignment. If it reports **diverged**, default to + merging `upstream/` into the current branch and preserving local commits. + For Sync Workflow, when the working tree is clean and you are behind upstream RC, + proceed with the fetch + merge without asking for additional confirmation. + +## Target RC Resolution + +The target RC is resolved dynamically so the workflow stays current as the RC changes. + +Resolution order: + +1. Latest `upstream/v*rc` branch (auto-detected) +2. `upstream/HEAD` (fallback) +3. If neither is available, you must pass `--rc ` + +Override for a single run: + +```bash +./check-sync.sh --rc +``` + +## Pre-Flight Checklist + +1. Confirm a clean working tree: + ```bash + git status + ``` +2. Confirm the current branch: + ```bash + git branch --show-current + ``` +3. Ensure remotes exist (origin + upstream): + ```bash + git remote -v + ``` + +## Sync Workflow (Upstream Sync) + +Use this flow when you are updating the current branch with fixes or improvements and +intend to keep origin and upstream RC in lockstep. + +1. **Check sync status** + ```bash + ./check-sync.sh + ``` +2. **Update from upstream RC before editing (no pulls)** + - **Behind upstream RC** → fetch and merge RC into your branch: + ```bash + git fetch upstream + git merge upstream/ --no-edit + ``` + When the working tree is clean and the user selected Sync Workflow, proceed without + an extra confirmation prompt. + - **Diverged** → stop and resolve manually. +3. **Resolve conflicts if needed** + - Handle conflicts intelligently: preserve upstream behavior and your local intent. +4. **Make changes and commit (if you are delivering fixes)** + ```bash + git add -A + git commit -m "type: description" + ``` +5. **Build to verify** + ```bash + npm run build:packages + npm run build + ``` +6. **Push after a successful merge to keep remotes aligned** + - If you only merged upstream RC changes, push **origin only** to sync your fork: + ```bash + git push origin + ``` + - If you have local fixes to publish, push **origin + upstream**: + ```bash + git push origin + git push upstream : + ``` + - Always ask the user which push to perform. + - Origin (origin-only sync): + ```bash + git push origin + ``` + - Upstream RC (publish the same fixes when you have local commits): + ```bash + git push upstream : + ``` +7. **Re-check sync** + ```bash + ./check-sync.sh + ``` + +## PR Workflow (Feature Work) + +Use this flow only for new feature work on a new branch. Do not push to upstream RC. + +1. **Create or switch to a feature branch** + ```bash + git checkout -b + ``` +2. **Make changes and commit** + ```bash + git add -A + git commit -m "type: description" + ``` +3. **Merge upstream RC before shipping** + ```bash + git merge upstream/ --no-edit + ``` +4. **Build and/or test** + ```bash + npm run build:packages + npm run build + ``` +5. **Push to origin** + ```bash + git push -u origin + ``` +6. **Create or update the PR** + - Use `gh pr create` or the GitHub UI. +7. **Review and follow-up** + +- Apply feedback, commit changes, and push again. +- Re-run `./check-sync.sh` if additional upstream sync is needed. + +## Conflict Resolution Checklist + +1. Identify which changes are from upstream vs. local. +2. Preserve both behaviors where possible; avoid dropping either side. +3. Prefer minimal, safe integrations over refactors. +4. Re-run build commands after resolving conflicts. +5. Re-run `./check-sync.sh` to confirm status. + +## Build/Test Matrix + +- **Sync Workflow**: `npm run build:packages` and `npm run build`. +- **PR Workflow**: `npm run build:packages` and `npm run build` (plus relevant tests). + +## Post-Sync Verification + +1. `git status` should be clean. +2. `./check-sync.sh` should show expected alignment. +3. Verify recent commits with: + ```bash + git log --oneline -5 + ``` + +## check-sync.sh Usage + +- Uses dynamic Target RC resolution (see above). +- Override target RC: + ```bash + ./check-sync.sh --rc + ``` +- Optional preview limit: + ```bash + ./check-sync.sh --preview 10 + ``` +- The script prints sync status for both origin and upstream and previews recent commits + when you are behind. + +## Stop Conditions + +Stop and ask for guidance if any of the following are true: + +- The working tree is dirty and you are about to merge or push. +- `./check-sync.sh` reports **diverged** during PR Workflow, or a merge cannot be completed. +- The script cannot resolve a target RC and requests `--rc`. +- A build fails after sync or conflict resolution. + +## AI Agent Guardrails + +- Always run `./check-sync.sh` before merges or pushes. +- Always ask for explicit user approval before any push command. +- Do not ask for additional confirmation before a Sync Workflow fetch + merge when the + working tree is clean and the user has already selected the Sync Workflow. +- Choose Sync vs PR workflow based on intent (RC maintenance vs new feature work), not + on the script's workflow hint. +- Only use force push when the user explicitly requests a history rewrite. +- Ask for explicit approval before dependency installs, branch deletion, or destructive operations. +- When resolving merge conflicts, preserve both upstream changes and local intent where possible. +- Do not create or switch to new branches unless the user explicitly requests it. + +## AI Agent Decision Guidance + +Agents should provide concrete, task-specific suggestions instead of repeatedly asking +open-ended questions. Use the user's stated goal and the `./check-sync.sh` status to +propose a default path plus one or two alternatives, and only ask for confirmation when +an action requires explicit approval. + +Default behavior: + +- If the intent is RC maintenance, recommend the Sync Workflow and proceed with + safe preparation steps (status checks, previews). If the branch is behind upstream RC, + fetch and merge without additional confirmation when the working tree is clean, then + push to origin to keep the fork aligned. Push upstream only when there are local fixes + to publish. +- If the intent is new feature work, recommend the PR Workflow and proceed with safe + preparation steps (status checks, identifying scope). Ask for approval before merges, + pushes, or dependency installs. +- If `./check-sync.sh` reports **diverged** during Sync Workflow, merge + `upstream/` into the current branch and preserve local commits. +- If `./check-sync.sh` reports **diverged** during PR Workflow, stop and ask for guidance + with a short explanation of the divergence and the minimal options to resolve it. + If the user's intent is RC maintenance, prefer the Sync Workflow regardless of the + script hint. When the intent is new feature work, use the PR Workflow and avoid upstream + RC pushes. + +Suggestion format (keep it short): + +- **Recommended**: one sentence with the default path and why it fits the task. +- **Alternatives**: one or two options with the tradeoff or prerequisite. +- **Approval points**: mention any upcoming actions that need explicit approval (exclude sync + workflow pushes and merges). + +## Failure Modes and How to Avoid Them + +Sync Workflow: + +- Wrong RC target: verify the auto-detected RC in `./check-sync.sh` output before merging. +- Diverged from upstream RC: stop and resolve manually before any merge or push. +- Dirty working tree: commit or stash before syncing to avoid accidental merges. +- Missing remotes: ensure both `origin` and `upstream` are configured before syncing. +- Build breaks after sync: run `npm run build:packages` and `npm run build` before pushing. + +PR Workflow: + +- Branch not synced to current RC: re-run `./check-sync.sh` and merge RC before shipping. +- Pushing the wrong branch: confirm `git branch --show-current` before pushing. +- Unreviewed changes: always commit and push to origin before opening or updating a PR. +- Skipped tests/builds: run the build commands before declaring the PR ready. + +## Notes + +- Avoid merging with uncommitted changes; commit or stash first. +- Prefer merge over rebase for PR branches; rebases rewrite history and often require a force push, + which should only be done with an explicit user request. +- Use clear, conventional commit messages and split unrelated changes into separate commits. diff --git a/check-sync.sh b/check-sync.sh new file mode 100755 index 00000000..81b5863e --- /dev/null +++ b/check-sync.sh @@ -0,0 +1,215 @@ +#!/usr/bin/env bash +set -euo pipefail + +DEFAULT_RC_PATTERN="v*rc" +DEFAULT_PREVIEW_COUNT=5 + +PREVIEW_COUNT="${PREVIEW_COUNT:-$DEFAULT_PREVIEW_COUNT}" +CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" + +ORIGIN_REF="origin/${CURRENT_BRANCH}" +TARGET_RC_SOURCE="auto" + +print_header() { + echo "=== Sync Status Check ===" + echo + printf "Target RC: %s (%s)\n" "$TARGET_RC" "$TARGET_RC_SOURCE" + echo +} + +ensure_git_repo() { + if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "Not inside a git repository." + exit 1 + fi +} + +ensure_remote() { + local remote="$1" + if ! git remote get-url "$remote" >/dev/null 2>&1; then + echo "Remote '$remote' is not configured." + exit 1 + fi +} + +fetch_remote() { + local remote="$1" + git fetch --quiet "$remote" +} + +warn_if_dirty() { + if [[ -n "$(git status --porcelain)" ]]; then + echo "Warning: working tree has uncommitted changes." + echo + fi +} + +resolve_target_rc() { + if [[ -n "${TARGET_RC:-}" ]]; then + return + fi + + local rc_candidates + rc_candidates="$(git for-each-ref --format='%(refname:short)' "refs/remotes/upstream/${DEFAULT_RC_PATTERN}" || true)" + if [[ -n "$rc_candidates" ]]; then + TARGET_RC="$(printf "%s\n" "$rc_candidates" | sed 's|^upstream/||' | sort -V | tail -n 1)" + TARGET_RC_SOURCE="auto:latest" + return + fi + + local upstream_head + upstream_head="$(git symbolic-ref --quiet --short refs/remotes/upstream/HEAD 2>/dev/null || true)" + if [[ -n "$upstream_head" ]]; then + TARGET_RC="${upstream_head#upstream/}" + TARGET_RC_SOURCE="auto:upstream-head" + return + fi + + echo "Unable to resolve target RC automatically. Use --rc ." + exit 1 +} + +ref_exists() { + local ref="$1" + git show-ref --verify --quiet "refs/remotes/${ref}" +} + +print_status_line() { + local label="$1" + local behind="$2" + local ahead="$3" + + if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then + printf "✅ %s: in sync (behind %s, ahead %s)\n" "$label" "$behind" "$ahead" + elif [[ "$behind" -eq 0 ]]; then + printf "⬆️ %s: ahead %s (behind %s)\n" "$label" "$ahead" "$behind" + elif [[ "$ahead" -eq 0 ]]; then + printf "⬇️ %s: behind %s (ahead %s)\n" "$label" "$behind" "$ahead" + else + printf "⚠️ %s: %s behind, %s ahead (diverged)\n" "$label" "$behind" "$ahead" + fi +} + +print_preview() { + local title="$1" + local range="$2" + + echo + echo "$title" + git log --oneline -n "$PREVIEW_COUNT" "$range" +} + +print_branch_context() { + echo "Branch: $CURRENT_BRANCH" + echo "Upstream RC: $UPSTREAM_REF" + echo "Upstream push: enabled for sync workflow" + echo +} + +print_upstream_summary() { + local behind="$1" + local ahead="$2" + + if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then + echo "Branch vs upstream RC: in sync (behind $behind, ahead $ahead)" + else + echo "Branch vs upstream RC: behind $behind, ahead $ahead" + fi +} + +print_workflow_hint() { + local behind="$1" + local ahead="$2" + + if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then + echo "Workflow: sync" + elif [[ "$behind" -gt 0 && "$ahead" -eq 0 ]]; then + echo "Workflow: sync (merge upstream RC)" + elif [[ "$ahead" -gt 0 && "$behind" -eq 0 ]]; then + echo "Workflow: pr (local work not in upstream)" + else + echo "Workflow: diverged (resolve manually)" + fi +} + +print_usage() { + echo "Usage: ./check-sync.sh [--rc ] [--preview ]" +} + +parse_args() { + while [[ $# -gt 0 ]]; do + case "$1" in + --rc) + shift + if [[ -z "${1-}" ]]; then + echo "Missing value for --rc" + exit 1 + fi + TARGET_RC="$1" + TARGET_RC_SOURCE="flag" + ;; + --preview) + shift + if [[ -z "${1-}" ]]; then + echo "Missing value for --preview" + exit 1 + fi + if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Invalid preview count: $1" + exit 1 + fi + PREVIEW_COUNT="$1" + ;; + -h|--help) + print_usage + exit 0 + ;; + *) + echo "Unknown argument: $1" + print_usage + exit 1 + ;; + esac + shift + done +} + +ensure_git_repo +ensure_remote origin +ensure_remote upstream +parse_args "$@" + +fetch_remote origin +fetch_remote upstream +resolve_target_rc + +UPSTREAM_REF="upstream/${TARGET_RC}" + +print_header +warn_if_dirty +print_branch_context + +if ! ref_exists "$ORIGIN_REF"; then + echo "Origin branch '$ORIGIN_REF' does not exist." +else + read -r origin_behind origin_ahead < <(git rev-list --left-right --count "$ORIGIN_REF...HEAD") + print_status_line "Origin" "$origin_behind" "$origin_ahead" +fi + +if ! ref_exists "$UPSTREAM_REF"; then + echo "Upstream ref '$UPSTREAM_REF' does not exist." +else + read -r upstream_behind upstream_ahead < <(git rev-list --left-right --count "$UPSTREAM_REF...HEAD") + print_status_line "Upstream" "$upstream_behind" "$upstream_ahead" + echo + print_upstream_summary "$upstream_behind" "$upstream_ahead" + print_workflow_hint "$upstream_behind" "$upstream_ahead" + + if [[ "$upstream_behind" -gt 0 ]]; then + print_preview "Recent upstream commits:" "HEAD..$UPSTREAM_REF" + fi + + if [[ "$upstream_ahead" -gt 0 ]]; then + print_preview "Commits on this branch not in upstream:" "$UPSTREAM_REF..HEAD" + fi +fi From 627580a8f0b14c99406123f64f7446767931c559 Mon Sep 17 00:00:00 2001 From: DhanushSantosh Date: Wed, 18 Feb 2026 11:58:57 +0530 Subject: [PATCH 3/3] chore: untrack check-sync.sh and DEVELOPMENT_WORKFLOW.md These are fork-local workflow tools already listed in .gitignore. Removing from git tracking so they persist locally across branch switches and are never accidentally staged or pushed. Co-Authored-By: Claude Sonnet 4.5 --- DEVELOPMENT_WORKFLOW.md | 253 ---------------------------------------- check-sync.sh | 215 ---------------------------------- 2 files changed, 468 deletions(-) delete mode 100644 DEVELOPMENT_WORKFLOW.md delete mode 100755 check-sync.sh diff --git a/DEVELOPMENT_WORKFLOW.md b/DEVELOPMENT_WORKFLOW.md deleted file mode 100644 index 0ce198ce..00000000 --- a/DEVELOPMENT_WORKFLOW.md +++ /dev/null @@ -1,253 +0,0 @@ -# Development Workflow - -This document defines the standard workflow for keeping a branch in sync with the upstream -release candidate (RC) and for shipping feature work. It is paired with `check-sync.sh`. - -## Quick Decision Rule - -1. Ask the user to select a workflow: - - **Sync Workflow** → you are maintaining the current RC branch with fixes/improvements - and will push the same fixes to both origin and upstream RC when you have local - commits to publish. - - **PR Workflow** → you are starting new feature work on a new branch; upstream updates - happen via PR only. -2. After the user selects, run: - ```bash - ./check-sync.sh - ``` -3. Use the status output to confirm alignment. If it reports **diverged**, default to - merging `upstream/` into the current branch and preserving local commits. - For Sync Workflow, when the working tree is clean and you are behind upstream RC, - proceed with the fetch + merge without asking for additional confirmation. - -## Target RC Resolution - -The target RC is resolved dynamically so the workflow stays current as the RC changes. - -Resolution order: - -1. Latest `upstream/v*rc` branch (auto-detected) -2. `upstream/HEAD` (fallback) -3. If neither is available, you must pass `--rc ` - -Override for a single run: - -```bash -./check-sync.sh --rc -``` - -## Pre-Flight Checklist - -1. Confirm a clean working tree: - ```bash - git status - ``` -2. Confirm the current branch: - ```bash - git branch --show-current - ``` -3. Ensure remotes exist (origin + upstream): - ```bash - git remote -v - ``` - -## Sync Workflow (Upstream Sync) - -Use this flow when you are updating the current branch with fixes or improvements and -intend to keep origin and upstream RC in lockstep. - -1. **Check sync status** - ```bash - ./check-sync.sh - ``` -2. **Update from upstream RC before editing (no pulls)** - - **Behind upstream RC** → fetch and merge RC into your branch: - ```bash - git fetch upstream - git merge upstream/ --no-edit - ``` - When the working tree is clean and the user selected Sync Workflow, proceed without - an extra confirmation prompt. - - **Diverged** → stop and resolve manually. -3. **Resolve conflicts if needed** - - Handle conflicts intelligently: preserve upstream behavior and your local intent. -4. **Make changes and commit (if you are delivering fixes)** - ```bash - git add -A - git commit -m "type: description" - ``` -5. **Build to verify** - ```bash - npm run build:packages - npm run build - ``` -6. **Push after a successful merge to keep remotes aligned** - - If you only merged upstream RC changes, push **origin only** to sync your fork: - ```bash - git push origin - ``` - - If you have local fixes to publish, push **origin + upstream**: - ```bash - git push origin - git push upstream : - ``` - - Always ask the user which push to perform. - - Origin (origin-only sync): - ```bash - git push origin - ``` - - Upstream RC (publish the same fixes when you have local commits): - ```bash - git push upstream : - ``` -7. **Re-check sync** - ```bash - ./check-sync.sh - ``` - -## PR Workflow (Feature Work) - -Use this flow only for new feature work on a new branch. Do not push to upstream RC. - -1. **Create or switch to a feature branch** - ```bash - git checkout -b - ``` -2. **Make changes and commit** - ```bash - git add -A - git commit -m "type: description" - ``` -3. **Merge upstream RC before shipping** - ```bash - git merge upstream/ --no-edit - ``` -4. **Build and/or test** - ```bash - npm run build:packages - npm run build - ``` -5. **Push to origin** - ```bash - git push -u origin - ``` -6. **Create or update the PR** - - Use `gh pr create` or the GitHub UI. -7. **Review and follow-up** - -- Apply feedback, commit changes, and push again. -- Re-run `./check-sync.sh` if additional upstream sync is needed. - -## Conflict Resolution Checklist - -1. Identify which changes are from upstream vs. local. -2. Preserve both behaviors where possible; avoid dropping either side. -3. Prefer minimal, safe integrations over refactors. -4. Re-run build commands after resolving conflicts. -5. Re-run `./check-sync.sh` to confirm status. - -## Build/Test Matrix - -- **Sync Workflow**: `npm run build:packages` and `npm run build`. -- **PR Workflow**: `npm run build:packages` and `npm run build` (plus relevant tests). - -## Post-Sync Verification - -1. `git status` should be clean. -2. `./check-sync.sh` should show expected alignment. -3. Verify recent commits with: - ```bash - git log --oneline -5 - ``` - -## check-sync.sh Usage - -- Uses dynamic Target RC resolution (see above). -- Override target RC: - ```bash - ./check-sync.sh --rc - ``` -- Optional preview limit: - ```bash - ./check-sync.sh --preview 10 - ``` -- The script prints sync status for both origin and upstream and previews recent commits - when you are behind. - -## Stop Conditions - -Stop and ask for guidance if any of the following are true: - -- The working tree is dirty and you are about to merge or push. -- `./check-sync.sh` reports **diverged** during PR Workflow, or a merge cannot be completed. -- The script cannot resolve a target RC and requests `--rc`. -- A build fails after sync or conflict resolution. - -## AI Agent Guardrails - -- Always run `./check-sync.sh` before merges or pushes. -- Always ask for explicit user approval before any push command. -- Do not ask for additional confirmation before a Sync Workflow fetch + merge when the - working tree is clean and the user has already selected the Sync Workflow. -- Choose Sync vs PR workflow based on intent (RC maintenance vs new feature work), not - on the script's workflow hint. -- Only use force push when the user explicitly requests a history rewrite. -- Ask for explicit approval before dependency installs, branch deletion, or destructive operations. -- When resolving merge conflicts, preserve both upstream changes and local intent where possible. -- Do not create or switch to new branches unless the user explicitly requests it. - -## AI Agent Decision Guidance - -Agents should provide concrete, task-specific suggestions instead of repeatedly asking -open-ended questions. Use the user's stated goal and the `./check-sync.sh` status to -propose a default path plus one or two alternatives, and only ask for confirmation when -an action requires explicit approval. - -Default behavior: - -- If the intent is RC maintenance, recommend the Sync Workflow and proceed with - safe preparation steps (status checks, previews). If the branch is behind upstream RC, - fetch and merge without additional confirmation when the working tree is clean, then - push to origin to keep the fork aligned. Push upstream only when there are local fixes - to publish. -- If the intent is new feature work, recommend the PR Workflow and proceed with safe - preparation steps (status checks, identifying scope). Ask for approval before merges, - pushes, or dependency installs. -- If `./check-sync.sh` reports **diverged** during Sync Workflow, merge - `upstream/` into the current branch and preserve local commits. -- If `./check-sync.sh` reports **diverged** during PR Workflow, stop and ask for guidance - with a short explanation of the divergence and the minimal options to resolve it. - If the user's intent is RC maintenance, prefer the Sync Workflow regardless of the - script hint. When the intent is new feature work, use the PR Workflow and avoid upstream - RC pushes. - -Suggestion format (keep it short): - -- **Recommended**: one sentence with the default path and why it fits the task. -- **Alternatives**: one or two options with the tradeoff or prerequisite. -- **Approval points**: mention any upcoming actions that need explicit approval (exclude sync - workflow pushes and merges). - -## Failure Modes and How to Avoid Them - -Sync Workflow: - -- Wrong RC target: verify the auto-detected RC in `./check-sync.sh` output before merging. -- Diverged from upstream RC: stop and resolve manually before any merge or push. -- Dirty working tree: commit or stash before syncing to avoid accidental merges. -- Missing remotes: ensure both `origin` and `upstream` are configured before syncing. -- Build breaks after sync: run `npm run build:packages` and `npm run build` before pushing. - -PR Workflow: - -- Branch not synced to current RC: re-run `./check-sync.sh` and merge RC before shipping. -- Pushing the wrong branch: confirm `git branch --show-current` before pushing. -- Unreviewed changes: always commit and push to origin before opening or updating a PR. -- Skipped tests/builds: run the build commands before declaring the PR ready. - -## Notes - -- Avoid merging with uncommitted changes; commit or stash first. -- Prefer merge over rebase for PR branches; rebases rewrite history and often require a force push, - which should only be done with an explicit user request. -- Use clear, conventional commit messages and split unrelated changes into separate commits. diff --git a/check-sync.sh b/check-sync.sh deleted file mode 100755 index 81b5863e..00000000 --- a/check-sync.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -DEFAULT_RC_PATTERN="v*rc" -DEFAULT_PREVIEW_COUNT=5 - -PREVIEW_COUNT="${PREVIEW_COUNT:-$DEFAULT_PREVIEW_COUNT}" -CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" - -ORIGIN_REF="origin/${CURRENT_BRANCH}" -TARGET_RC_SOURCE="auto" - -print_header() { - echo "=== Sync Status Check ===" - echo - printf "Target RC: %s (%s)\n" "$TARGET_RC" "$TARGET_RC_SOURCE" - echo -} - -ensure_git_repo() { - if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then - echo "Not inside a git repository." - exit 1 - fi -} - -ensure_remote() { - local remote="$1" - if ! git remote get-url "$remote" >/dev/null 2>&1; then - echo "Remote '$remote' is not configured." - exit 1 - fi -} - -fetch_remote() { - local remote="$1" - git fetch --quiet "$remote" -} - -warn_if_dirty() { - if [[ -n "$(git status --porcelain)" ]]; then - echo "Warning: working tree has uncommitted changes." - echo - fi -} - -resolve_target_rc() { - if [[ -n "${TARGET_RC:-}" ]]; then - return - fi - - local rc_candidates - rc_candidates="$(git for-each-ref --format='%(refname:short)' "refs/remotes/upstream/${DEFAULT_RC_PATTERN}" || true)" - if [[ -n "$rc_candidates" ]]; then - TARGET_RC="$(printf "%s\n" "$rc_candidates" | sed 's|^upstream/||' | sort -V | tail -n 1)" - TARGET_RC_SOURCE="auto:latest" - return - fi - - local upstream_head - upstream_head="$(git symbolic-ref --quiet --short refs/remotes/upstream/HEAD 2>/dev/null || true)" - if [[ -n "$upstream_head" ]]; then - TARGET_RC="${upstream_head#upstream/}" - TARGET_RC_SOURCE="auto:upstream-head" - return - fi - - echo "Unable to resolve target RC automatically. Use --rc ." - exit 1 -} - -ref_exists() { - local ref="$1" - git show-ref --verify --quiet "refs/remotes/${ref}" -} - -print_status_line() { - local label="$1" - local behind="$2" - local ahead="$3" - - if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then - printf "✅ %s: in sync (behind %s, ahead %s)\n" "$label" "$behind" "$ahead" - elif [[ "$behind" -eq 0 ]]; then - printf "⬆️ %s: ahead %s (behind %s)\n" "$label" "$ahead" "$behind" - elif [[ "$ahead" -eq 0 ]]; then - printf "⬇️ %s: behind %s (ahead %s)\n" "$label" "$behind" "$ahead" - else - printf "⚠️ %s: %s behind, %s ahead (diverged)\n" "$label" "$behind" "$ahead" - fi -} - -print_preview() { - local title="$1" - local range="$2" - - echo - echo "$title" - git log --oneline -n "$PREVIEW_COUNT" "$range" -} - -print_branch_context() { - echo "Branch: $CURRENT_BRANCH" - echo "Upstream RC: $UPSTREAM_REF" - echo "Upstream push: enabled for sync workflow" - echo -} - -print_upstream_summary() { - local behind="$1" - local ahead="$2" - - if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then - echo "Branch vs upstream RC: in sync (behind $behind, ahead $ahead)" - else - echo "Branch vs upstream RC: behind $behind, ahead $ahead" - fi -} - -print_workflow_hint() { - local behind="$1" - local ahead="$2" - - if [[ "$behind" -eq 0 && "$ahead" -eq 0 ]]; then - echo "Workflow: sync" - elif [[ "$behind" -gt 0 && "$ahead" -eq 0 ]]; then - echo "Workflow: sync (merge upstream RC)" - elif [[ "$ahead" -gt 0 && "$behind" -eq 0 ]]; then - echo "Workflow: pr (local work not in upstream)" - else - echo "Workflow: diverged (resolve manually)" - fi -} - -print_usage() { - echo "Usage: ./check-sync.sh [--rc ] [--preview ]" -} - -parse_args() { - while [[ $# -gt 0 ]]; do - case "$1" in - --rc) - shift - if [[ -z "${1-}" ]]; then - echo "Missing value for --rc" - exit 1 - fi - TARGET_RC="$1" - TARGET_RC_SOURCE="flag" - ;; - --preview) - shift - if [[ -z "${1-}" ]]; then - echo "Missing value for --preview" - exit 1 - fi - if ! [[ "$1" =~ ^[0-9]+$ ]]; then - echo "Invalid preview count: $1" - exit 1 - fi - PREVIEW_COUNT="$1" - ;; - -h|--help) - print_usage - exit 0 - ;; - *) - echo "Unknown argument: $1" - print_usage - exit 1 - ;; - esac - shift - done -} - -ensure_git_repo -ensure_remote origin -ensure_remote upstream -parse_args "$@" - -fetch_remote origin -fetch_remote upstream -resolve_target_rc - -UPSTREAM_REF="upstream/${TARGET_RC}" - -print_header -warn_if_dirty -print_branch_context - -if ! ref_exists "$ORIGIN_REF"; then - echo "Origin branch '$ORIGIN_REF' does not exist." -else - read -r origin_behind origin_ahead < <(git rev-list --left-right --count "$ORIGIN_REF...HEAD") - print_status_line "Origin" "$origin_behind" "$origin_ahead" -fi - -if ! ref_exists "$UPSTREAM_REF"; then - echo "Upstream ref '$UPSTREAM_REF' does not exist." -else - read -r upstream_behind upstream_ahead < <(git rev-list --left-right --count "$UPSTREAM_REF...HEAD") - print_status_line "Upstream" "$upstream_behind" "$upstream_ahead" - echo - print_upstream_summary "$upstream_behind" "$upstream_ahead" - print_workflow_hint "$upstream_behind" "$upstream_ahead" - - if [[ "$upstream_behind" -gt 0 ]]; then - print_preview "Recent upstream commits:" "HEAD..$UPSTREAM_REF" - fi - - if [[ "$upstream_ahead" -gt 0 ]]; then - print_preview "Commits on this branch not in upstream:" "$UPSTREAM_REF..HEAD" - fi -fi