Skip to content

Commit 0291ddf

Browse files
committed
ci: align fork workflows and fix installer pipeline failures
1 parent ce33ab6 commit 0291ddf

8 files changed

Lines changed: 76 additions & 43 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: 38 additions & 26 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,30 +127,30 @@ 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

docs/fork-workflow-strategy.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ graph TD
2828
U -->|Action: Daily Sync| I
2929
F1 -->|PR: Merge| I
3030
F2 -->|PR: Merge| I
31-
31+
3232
style I fill:#d4edda,stroke:#28a745,stroke-width:2px
3333
style U fill:#cce5ff,stroke:#004085,stroke-width:2px
3434
```
@@ -39,6 +39,13 @@ Your GitHub Action `upstream-sync.yml` runs daily.
3939
- It attempts to merge into `local-desktop-installation-support`.
4040
- **If Clean**: It pushes automatically. You wake up to a fresh, up-to-date repo.
4141
- **If Conflict**: It opens a PR with conflict markers. You must resolve it (see [Upstream Sync Guide](./upstream-sync.md)).
42+
- **Token Requirement**: Configure `UPSTREAM_SYNC_TOKEN` so mirror pushes can update `.github/workflows/*` when upstream changes those files.
43+
44+
### 1.5 CI Branch Alignment
45+
`Installer CI` should run on `local-desktop-installation-support` (and PRs targeting it), because that is the deployment/integration branch.
46+
47+
- Keep `main` as an upstream mirror branch.
48+
- Use CI on `local-desktop-installation-support` to validate what actually lands on your machine.
4249
### 2. Developing a New Feature (The "Right Way")
4350
**NEVER** work directly on `local-desktop-installation-support`. Always use a feature branch.
4451
#### Step 1: Start Fresh

docs/upstream-sync.md

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

1313
## Workflow Logic
1414
1. **Daily Trigger**: Runs at 00:00 UTC.
15-
2. **Sync**: Merges `upstream/main` into a branch named `upstream-sync`.
16-
3. **Conflict Handling**:
17-
- **Clean Merge**: Creates a PR with merged changes.
18-
- **Conflict**: Commits files *with conflict markers* to the PR so you can see them in the diff.
19-
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.
15+
2. **Mirror Main**: Hard-resets fork `main` to `upstream/main` and force-pushes.
16+
3. **Integrate**: Merges fork `main` into `local-desktop-installation-support` through `upstream-sync`.
17+
4. **Conflict Handling**:
18+
- **Clean Merge**: Automatically pushes the updates to your target branch (`local-desktop-installation-support`). No PR is created.
19+
- **Conflict**: Commits files *with conflict markers* to a new branch and creates a PR so you can resolve them.
20+
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.
2021

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

2433
1. **Go to Settings**: Navigate to your GitHub repository page and click on the **Settings** tab.
2534
2. **Access Secrets**: In the left sidebar, click on **Secrets and variables**, then select **Actions**.
@@ -66,3 +75,5 @@ To run the sync manually:
6675
2. Select **Upstream Sync** from the left sidebar.
6776
3. Click **Run workflow**.
6877
4. Select the branch and click **Run workflow**.
78+
79+
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)