Skip to content

Commit 342af70

Browse files
committed
ci: align fork workflows and fix installer pipeline failures
1 parent 99c1d18 commit 342af70

8 files changed

Lines changed: 75 additions & 42 deletions

File tree

.github/workflows/installer.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Installer CI
22

33
on:
44
push:
5-
branches: [main]
5+
branches: [local-desktop-installation-support]
66
paths:
77
- 'install.sh'
88
- 'scripts/**'
@@ -13,7 +13,7 @@ on:
1313
- '.shellcheckrc'
1414
- 'tests/**/*.sh'
1515
pull_request:
16-
branches: [main]
16+
branches: [local-desktop-installation-support]
1717
paths:
1818
- 'install.sh'
1919
- 'scripts/**'
@@ -187,7 +187,7 @@ jobs:
187187
path: result.json
188188

189189
pinned-ref-smoke:
190-
name: Pinned Ref Smoke (checksums from main)
190+
name: Pinned Ref Smoke (checksums from integration branch)
191191
runs-on: ubuntu-latest
192192
timeout-minutes: 30
193193
container:
@@ -209,10 +209,10 @@ jobs:
209209
echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-ci-ubuntu
210210
chmod 440 /etc/sudoers.d/90-ci-ubuntu
211211
212-
- name: Run pinned-ref install (checksums from main)
212+
- name: Run pinned-ref install (checksums from integration branch)
213213
run: |
214214
ACFS_REF="$(cat VERSION)" \
215-
ACFS_CHECKSUMS_REF=main \
215+
ACFS_CHECKSUMS_REF=local-desktop-installation-support \
216216
bash install.sh --yes --skip-preflight --skip-ubuntu-upgrade --mode safe --only lang.uv
217217
218218
selection-tests:
@@ -249,7 +249,7 @@ jobs:
249249
include:
250250
- ubuntu: '24.04'
251251
mode: vibe
252-
- ubuntu: '25.04'
252+
- ubuntu: '25.10'
253253
mode: vibe
254254
- ubuntu: '24.04'
255255
mode: safe

.github/workflows/upstream-sync.yml

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
- cron: '0 0 * * *' # Daily at midnight
66
workflow_dispatch:
77

8+
concurrency:
9+
group: upstream-sync
10+
cancel-in-progress: false
11+
812
permissions:
913
contents: write
1014
pull-requests: write
@@ -14,19 +18,26 @@ jobs:
1418
sync:
1519
runs-on: ubuntu-latest
1620
env:
17-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18-
MAIN_BRANCH: main
19-
TARGET_BRANCH: local-desktop-installation-support
20-
SYNC_BRANCH: upstream-sync
21-
UPSTREAM_URL: https://github.com/Dicklesworthstone/agentic_coding_flywheel_setup.git
22-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
21+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
PUSH_TOKEN: ${{ secrets.UPSTREAM_SYNC_TOKEN }}
23+
MAIN_BRANCH: main
24+
TARGET_BRANCH: local-desktop-installation-support
25+
SYNC_BRANCH: upstream-sync
26+
UPSTREAM_URL: https://github.com/Dicklesworthstone/agentic_coding_flywheel_setup.git
27+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
2328

2429
steps:
2530
- name: Checkout
2631
uses: actions/checkout@v4
2732
with:
2833
fetch-depth: 0
2934
ref: ${{ env.MAIN_BRANCH }}
35+
token: ${{ secrets.UPSTREAM_SYNC_TOKEN != '' && secrets.UPSTREAM_SYNC_TOKEN || secrets.GITHUB_TOKEN }}
36+
37+
- name: Warn if mirror token is missing
38+
if: env.PUSH_TOKEN == ''
39+
run: |
40+
echo "::warning::UPSTREAM_SYNC_TOKEN is not configured. Pushes that update .github/workflows may be rejected."
3041
3142
- name: Configure Git
3243
run: |
@@ -40,29 +51,33 @@ jobs:
4051

4152
- name: Add and Fetch Upstream
4253
run: |
43-
git remote add upstream "$UPSTREAM_URL"
54+
if git remote get-url upstream >/dev/null 2>&1; then
55+
git remote set-url upstream "$UPSTREAM_URL"
56+
else
57+
git remote add upstream "$UPSTREAM_URL"
58+
fi
4459
git fetch upstream
4560
4661
# Step 1: Sync fork's main branch with upstream/main (Pure Mirror)
4762
- name: Sync Main Branch with Upstream
4863
run: |
4964
echo "Syncing fork's main branch with upstream/main..."
50-
65+
5166
# Hard reset main to match upstream/main exactly
5267
git checkout "$MAIN_BRANCH"
5368
git reset --hard upstream/main
54-
69+
5570
# Force push to update the fork's main branch
5671
git push -f origin "$MAIN_BRANCH"
57-
72+
5873
echo "✅ Fork's main branch is now a pure mirror of upstream/main"
5974
6075
# Step 2: Merge main into local-desktop-installation-support
6176
- name: Prepare Integration Branch
6277
run: |
6378
# Checkout the integration branch
6479
git checkout "$TARGET_BRANCH"
65-
80+
6681
# Create/reset sync branch from target for the merge
6782
git checkout -B "$SYNC_BRANCH" "$TARGET_BRANCH"
6883
@@ -98,9 +113,6 @@ jobs:
98113
# Ensure labels exist to prevent errors during PR creation
99114
gh label create upstream-sync --repo ${{ github.repository }} --description "Syncs changes from upstream" --color 1d76db || true
100115
gh label create conflict --repo ${{ github.repository }} --description "Merge conflicts detected" --color b60205 || true
101-
102-
# Debug: List labels to verify visibility
103-
gh label list --repo ${{ github.repository }}
104116
105117
# Step 3: Handle result based on merge status
106118
- name: Push Clean Merge Directly
@@ -115,35 +127,35 @@ jobs:
115127
run: |
116128
# Check if PR already exists
117129
existing_pr=$(gh pr list --repo ${{ github.repository }} --head "$SYNC_BRANCH" --base "$TARGET_BRANCH" --json number -q '.[0].number')
118-
130+
119131
if [[ -z "$existing_pr" ]]; then
120132
echo "Creating new PR for conflict resolution..."
121133
TITLE="⚠️ Upstream Sync (Conflicts Detected)"
122134
BODY="This PR syncs changes from upstream. **Conflicts were detected and committed with markers.** Please review and resolve them."
123-
LABELS="upstream-sync,conflict"
124-
135+
125136
PR_URL=$(gh pr create \
126137
--repo ${{ github.repository }} \
127138
--title "$TITLE" \
128139
--body "$BODY" \
129140
--head "$SYNC_BRANCH" \
130141
--base "$TARGET_BRANCH" \
131-
--label "$LABELS")
132-
142+
--label "upstream-sync" \
143+
--label "conflict")
144+
133145
echo "PR_URL=$PR_URL" >> "$GITHUB_ENV"
134146
else
135-
echo "Updating existing PR #$existing_pr..."
136-
echo "PR_URL=https://github.com/${{ github.repository }}/pull/$existing_pr" >> "$GITHUB_ENV"
137-
138-
gh pr edit "$existing_pr" --repo ${{ github.repository }} \
139-
--title "⚠️ Upstream Sync (Conflicts Detected)" \
140-
--add-label "conflict" \
141-
--body "Updates from upstream. Conflicts detected."
147+
echo "Updating existing PR #$existing_pr..."
148+
echo "PR_URL=https://github.com/${{ github.repository }}/pull/$existing_pr" >> "$GITHUB_ENV"
149+
150+
gh pr edit "$existing_pr" --repo ${{ github.repository }} \
151+
--title "⚠️ Upstream Sync (Conflicts Detected)" \
152+
--add-label "conflict" \
153+
--body "Updates from upstream. Conflicts detected."
142154
fi
143155
144156
- name: Analyze Conflicts with AI
145157
if: steps.merge.outputs.merge_status == 'conflict' && env.OPENAI_API_KEY != ''
146158
run: |
147159
echo "Analyzing conflicts..."
148160
# Run the analysis script
149-
bun run ./scripts/analyze-conflicts.ts "${{ env.PR_URL }}"
161+
bun run ./scripts/analyze-conflicts.ts "${{ env.PR_URL }}"

docs/fork-workflow-strategy.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ graph TD
3838
U -->|Action: Daily Sync| I
3939
F1 -->|PR: Merge| I
4040
F2 -->|PR: Merge| I
41-
41+
4242
style I fill:#d4edda,stroke:#28a745,stroke-width:2px
4343
style U fill:#cce5ff,stroke:#004085,stroke-width:2px
4444
```
@@ -51,6 +51,13 @@ Your GitHub Action `upstream-sync.yml` runs daily.
5151
- It attempts to merge into `local-desktop-installation-support`.
5252
- **If Clean**: It pushes automatically. You wake up to a fresh, up-to-date repo.
5353
- **If Conflict**: It opens a PR with conflict markers. You must resolve it (see [Upstream Sync Guide](./upstream-sync.md)).
54+
- **Token Requirement**: Configure `UPSTREAM_SYNC_TOKEN` so mirror pushes can update `.github/workflows/*` when upstream changes those files.
55+
56+
### 1.5 CI Branch Alignment
57+
`Installer CI` should run on `local-desktop-installation-support` (and PRs targeting it), because that is the deployment/integration branch.
58+
59+
- Keep `main` as an upstream mirror branch.
60+
- Use CI on `local-desktop-installation-support` to validate what actually lands on your machine.
5461

5562
### 2. Developing a New Feature (The "Right Way")
5663

docs/upstream-sync.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,23 @@ A GitHub Action (`.github/workflows/upstream-sync.yml`) automatically syncs chan
1414

1515
## Workflow Logic
1616
1. **Daily Trigger**: Runs at 00:00 UTC.
17-
2. **Sync**: Merges `upstream/main` into a branch named `upstream-sync`.
18-
3. **Conflict Handling**:
17+
2. **Mirror Main**: Hard-resets fork `main` to `upstream/main` and force-pushes.
18+
3. **Integrate**: Merges fork `main` into `local-desktop-installation-support` through `upstream-sync`.
19+
4. **Conflict Handling**:
1920
- **Clean Merge**: Automatically pushes the updates to your target branch (`local-desktop-installation-support`). No PR is created.
2021
- **Conflict**: Commits files *with conflict markers* to a new branch and creates a PR so you can resolve them.
21-
4. **AI Analysis**: If conflicts exist AND `OPENAI_API_KEY` is set in repository secrets, an AI suggestion is posted as a comment on the PR.
22+
5. **AI Analysis**: If conflicts exist AND `OPENAI_API_KEY` is set in repository secrets, an AI suggestion is posted as a comment on the PR.
2223

23-
## Configuration: Setting up the API Key
24-
To enable AI conflict analysis, you must securely add your OpenAI API Key to the repository secrets.
24+
## Configuration: Required Secrets
25+
26+
### 1) `UPSTREAM_SYNC_TOKEN` (required for reliable mirror pushes)
27+
Use a token that can push repository contents and workflow files, then store it as:
28+
- **Name**: `UPSTREAM_SYNC_TOKEN`
29+
30+
Without this secret, pushes that include `.github/workflows/*` changes can be rejected by GitHub.
31+
32+
### 2) `OPENAI_API_KEY` (optional for AI conflict analysis)
33+
To enable AI conflict analysis, securely add your OpenAI API Key to repository secrets.
2534

2635
1. **Go to Settings**: Navigate to your GitHub repository page and click on the **Settings** tab.
2736
2. **Access Secrets**: In the left sidebar, click on **Secrets and variables**, then select **Actions**.
@@ -68,3 +77,5 @@ To run the sync manually:
6877
2. Select **Upstream Sync** from the left sidebar.
6978
3. Click **Run workflow**.
7079
4. Select the branch and click **Run workflow**.
80+
81+
For consistency with the integration-branch strategy, run it from `main`.

scripts/check-manifest-drift.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ log "Manifest SHA256 now matches: $ACTUAL_NOW"
224224
if [[ -f "$INTERNAL_CHECKSUMS_FILE" ]] && [[ "$INTERNAL_DRIFT_COUNT" -gt 0 ]]; then
225225
log "Verifying internal script checksums after regeneration..."
226226
unset ACFS_INTERNAL_CHECKSUMS
227+
# shellcheck source=scripts/generated/internal_checksums.sh
227228
source "$INTERNAL_CHECKSUMS_FILE"
228229
post_fix_drift=0
229230
for rel_path in "${!ACFS_INTERNAL_CHECKSUMS[@]}"; do

scripts/generated/internal_checksums.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ declare -gA ACFS_INTERNAL_CHECKSUMS=(
1818
[scripts/lib/session.sh]="f008658acc15c08929013d46af33f62ca4306cafaf5cf3344bd0626e3e41f137"
1919
[scripts/lib/os_detect.sh]="ebc49bc9742e0e65b27d350eba0b67a9ae270298254ef4e71a97967b476b83d9"
2020
[scripts/lib/errors.sh]="79a9e37babd77f2bcdf110c7f805c6352983e81fe8c29a6ad61cc8df69d7f0e7"
21-
[scripts/lib/user.sh]="767910abfa2d59c6ef1147a91e9571395f481b2dd0135d983e576b64f25da0bc"
21+
[scripts/lib/user.sh]="7bcc8691c0174f0ec871234a4d8de3032143768a9caa587b04395e98c22654f1"
2222
[scripts/lib/tools.sh]="325f8ad08a07fec4c489092a925ac9d6009ab88d3d71cff4ccf5d41acaaf94e9"
2323
[scripts/lib/export-config.sh]="731732f60e13169554488f154e81225d1a73f3521ce28cae0ebc00e78f69f85f"
2424
[scripts/acfs-global]="ac2d5dc4f19e4ebfa9b354c7c22f96ec9b82e1975abe89249d07b0610197931b"

tests/vm/bootstrap_offline_checks.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ create_archive() {
4949
cp -R "$REPO_ROOT/scripts/lib" "$stage_dir/acfs-offline/scripts/"
5050
cp -R "$REPO_ROOT/scripts/generated" "$stage_dir/acfs-offline/scripts/"
5151
cp "$REPO_ROOT/scripts/preflight.sh" "$stage_dir/acfs-offline/scripts/preflight.sh"
52+
cp "$REPO_ROOT/scripts/acfs-global" "$stage_dir/acfs-offline/scripts/acfs-global"
53+
cp "$REPO_ROOT/scripts/acfs-update" "$stage_dir/acfs-offline/scripts/acfs-update"
5254

5355
cp -R "$REPO_ROOT/acfs" "$stage_dir/acfs-offline/acfs"
5456
cp "$REPO_ROOT/checksums.yaml" "$stage_dir/acfs-offline/checksums.yaml"

tests/vm/test_macos_bootstrap.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ run_case_one() {
240240
fi
241241

242242
local event_log
243-
event_log="$(ls -1 "$home_dir/.acfs/logs/install/"*.jsonl 2>/dev/null | head -n1 || true)"
243+
event_log="$(find "$home_dir/.acfs/logs/install" -maxdepth 1 -type f -name '*.jsonl' 2>/dev/null | sort | head -n1 || true)"
244244
if [[ -n "$event_log" ]] && grep -q '"event":"install_start"' "$event_log" && grep -q '"event":"install_end"' "$event_log"; then
245245
pass "writes host observability install_start/install_end events"
246246
else
@@ -312,7 +312,7 @@ EOF
312312
bash -s -- --macos --yes < "$REPO_ROOT/install.sh"
313313

314314
local event_log
315-
event_log="$(ls -1 "$home_dir/.acfs/logs/install/"*.jsonl 2>/dev/null | head -n1 || true)"
315+
event_log="$(find "$home_dir/.acfs/logs/install" -maxdepth 1 -type f -name '*.jsonl' 2>/dev/null | sort | head -n1 || true)"
316316
if [[ -n "$event_log" ]] && grep -q '"event":"resume"' "$event_log"; then
317317
pass "emits resume event when prior host bootstrap state is incomplete"
318318
else

0 commit comments

Comments
 (0)