Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
42c3d7a
Fix merge-fix workflow to handle conflict markers before install (#16…
matthewp Apr 30, 2026
425fa8b
Handle merge conflicts in merge-fix workflow by stripping JSON/YAML m…
matthewp Apr 30, 2026
c1fe832
[ci] format
matthewp Apr 30, 2026
86fd80d
fix(render): avoid script dedup state consumption in inert template c…
enjoyandlove Apr 30, 2026
4ff42fd
[ci] format
matthewp Apr 30, 2026
280ec88
fix: emit fallback rewrite pages (#16515)
jp-knj May 1, 2026
8eaaaaf
[ci] format
ematipico May 1, 2026
72ba0b1
refactor(astro): replace tsconfck with get-tsconfig (#16433)
ocavue May 1, 2026
646b247
fix(language-server): remove circular dependency on svelte/vue integr…
ocavue May 1, 2026
2dd5703
[ci] format
ematipico May 1, 2026
b31f861
fix(upgrade): use bundled JS output (#16547)
ocavue May 1, 2026
38958d4
Update dependency postcss to v8.5.10 [SECURITY] (#16489)
renovate[bot] May 1, 2026
48baf7f
Update dependency fastify to v5.8.5 [SECURITY] (#16346)
renovate[bot] May 1, 2026
b4791e3
Update dependency fast-xml-parser to v5.7.0 [SECURITY] (#16452)
renovate[bot] May 1, 2026
7746a13
fix(cloudflare): preserve existing KV namespace bindings when injecti…
May 1, 2026
d3d3557
fix(slots): unwrap conditional slot callbacks (#16509)
cyphercodes May 1, 2026
559c0fd
fix: preserve CSS propagation for partial pages imported as component…
0xbejaxer May 1, 2026
00f48ee
fix: propagate head metadata across ssr and prerender envs in dev (#1…
p-linnane May 1, 2026
778865f
fix(assets): pass through images Sharp cannot decode instead of crash…
maximslo May 1, 2026
611029b
[ci] format
matthewp May 1, 2026
06e6878
Update dependency @fastify/middie to v9.3.2 [SECURITY] (#16369)
renovate[bot] May 1, 2026
e59c637
perf(astro): skip session storage lookup if no cookie is set (#16540)
ascorbic May 1, 2026
d14f47c
Fix defineLiveCollection interface loader typing (#16018)
felmonon May 1, 2026
e46b4de
[ci] format
matthewp May 1, 2026
1e70d18
Fix style compilation failure when importing components via tsconfig …
ossaidqadri May 1, 2026
7666bcd
fix(cloudflare): fix static assets and prerendered pages 404ing when …
Calvin-LL May 1, 2026
5b0dc6c
[ci] format
matthewp May 1, 2026
4b2a2ef
fix(test): update test-utils import from .js to .ts in .test.js files…
matthewp May 1, 2026
409f6ef
fix(frontmatter): preserve strings and comments when replacing top-le…
May 1, 2026
1cd6650
fix: processing procedure for dynamic paths (#16144)
fkatsuhiro May 1, 2026
7214d3e
fix(css): preserve scope on nested & with lightningcss transformer (#…
senutpal May 1, 2026
9f4eee0
Fixes @_@ not being stripped from CSS file names (#16264)
atsbob May 1, 2026
c6b068e
fix : astro image position prop bug (#16236)
fkatsuhiro May 1, 2026
a595623
[ci] format
matthewp May 1, 2026
6ab0b3c
fix(build): exclude prerendered route styles from SSR manifest (#16517)
adamchal May 1, 2026
9ac96b4
fix(prefetch): trigger tap strategy when clicking nested child elemen…
May 1, 2026
7959798
fix(astro): persist session delete without prior get/set (#16565)
enjoyandlove May 1, 2026
17f1867
fix: route mismatch using trail slash never (#16516)
fkatsuhiro May 2, 2026
7711e47
[ci] format
ematipico May 2, 2026
3f67b84
[ci] release (#16545)
astrobot-houston May 4, 2026
047cb99
chore: merge main into next (conflicts)
astrobot-houston May 4, 2026
faa6e19
fix: resolve merge conflicts from main into next
matthewp May 4, 2026
2f6c3b9
fix: resolve merge issues from main into next
astrobot-houston May 4, 2026
debcbb4
chore: trigger CI
matthewp May 4, 2026
84ae928
fix: add head-inject directive to propagated assets module for CSS in…
matthewp May 4, 2026
be11f72
chore: update main-to-next merge
astrobot-houston May 4, 2026
41ba7fb
chore: retrigger CI
matthewp May 4, 2026
17f1c4f
chore: retrigger CI
matthewp May 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions .agents/skills/merge/fix-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ This skill follows a "fix and push" approach. After pushing, CI will re-run auto

## Steps

### Step 1: Get CI failure logs
### Step 1: Build all packages

Before analyzing test failures, ensure all packages are built:

```bash
pnpm build
```

Fix any build errors first — these may be the cause of test failures downstream.

### Step 2: Get CI failure logs

Use the GitHub CLI to find the failed CI run and download its logs:

Expand All @@ -35,7 +45,7 @@ Parse the output to identify:
- The specific test names that failed
- The error messages and assertion diffs

### Step 2: Analyze failures
### Step 3: Analyze failures

For each failure, determine the cause:

Expand All @@ -47,7 +57,7 @@ For each failure, determine the cause:

4. **Configuration mismatches** — Test fixtures using config options that changed on `next`. Fix by updating the fixture config.

### Step 3: Fix the failures
### Step 4: Fix the failures

For each failure:

Expand All @@ -68,7 +78,7 @@ For each failure:
- Smoke tests — these are allowed to fail
- `astro check` failures — these are permitted to fail

### Step 4: Verify fixes locally (targeted only)
### Step 5: Verify fixes locally (targeted only)

Only run the specific tests you fixed, not the full suite:

Expand All @@ -78,7 +88,7 @@ pnpm -C <package-directory> exec astro-scripts test "test/<specific-test>.test.j

This is a quick sanity check, not a replacement for CI. CI will do the full validation after you push.

### Step 5: Rebuild if source files were modified
### Step 6: Rebuild if source files were modified

If you modified any source files in `packages/` (not just test files), rebuild the affected package:

Expand All @@ -88,7 +98,7 @@ pnpm -C packages/<affected-package> build

Then re-run the specific affected tests to confirm.

### Step 6: Ensure dependencies are up to date
### Step 7: Ensure dependencies are up to date

If the merge introduced new dependencies or changed versions, run:

Expand Down
76 changes: 46 additions & 30 deletions .agents/skills/merge/resolve-conflicts.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,73 @@
# Resolve Merge Conflicts
# Verify Merge Conflict Resolutions

Resolve merge conflicts from merging `main` into the `next` branch.
Verify that the automated conflict resolution (which kept the "ours"/next side for JSON and YAML files) was correct, and fix any issues.

**SCOPE: Do not spawn tasks/sub-agents.**

## Prerequisites

- **`prNumber`** — The PR number for the merge PR.
- **`branch`** — The branch name (e.g., `ci/merge-main-to-next`).
- The working directory is the repo root, checked out on the merge branch with conflict markers present.
- The working directory is the repo root, checked out on the merge branch.
- Dependencies are installed and packages are built.
- Conflict markers in JSON/YAML files have already been stripped by the GitHub Action, keeping the "ours" (next) side. Source code files (`.ts`, `.js`, `.md`, `.astro`) may still have conflict markers.

## Strategy
## Background

When resolving conflicts, follow these rules based on file type:
The GitHub Action strips conflict markers from JSON/YAML files before `pnpm install` can run, always keeping the `next` branch side. This is usually correct (next has pre-release versions that must be preserved), but it may discard important changes from `main` — like new dependencies, updated dependency versions, or config changes from bug fixes.

### Changeset files (`.changeset/*.md`)

- If a changeset file exists on `main` but not on `next`, it was likely already released. **Delete it.** The clean-changesets skill will handle this more thoroughly, but removing obvious ones here unblocks the merge.
- If both branches modified the same changeset, prefer the `next` version since it's the one targeting the upcoming major.

### `package.json` and version files
## Steps

- **Prefer `next` branch versions.** The `next` branch has the pre-release versions (alpha/beta) which should not be overwritten by `main`'s stable versions.
- For dependency version updates from `main`, accept those — they are typically patches/minors that should be forward-ported.
### Step 1: Resolve any remaining conflict markers

### `pnpm-lock.yaml`
Check for conflict markers in source code files:

- Do not try to manually resolve lockfile conflicts. Instead:
1. Accept the `next` version: `git checkout --theirs pnpm-lock.yaml`
2. The lockfile will be regenerated after `pnpm install` later.
```bash
grep -r "<<<<<<< " --include="*.ts" --include="*.js" --include="*.mjs" --include="*.cjs" --include="*.md" --include="*.astro" . 2>/dev/null | grep -v node_modules
```

### Source code (`packages/**/*.ts`, `packages/**/*.js`)
If any exist, resolve them following these rules:

- **Prefer `main` for bug fixes.** If `main` fixed a bug, that fix should carry over to `next`.
- **Prefer `next` for API changes.** If `next` changed an API (new major version features), keep the `next` version and adapt the `main` fix to work with it if needed.
- **Prefer `next` for API changes.** If `next` changed an API, keep the `next` version and adapt the `main` fix if needed.
- When in doubt, prefer `next` — it's the forward-looking branch.

### Test files
After resolving, `git add` each file.

- If tests conflict, prefer `next` and adapt. Tests on `next` may test new major-version behavior.
### Step 2: Review what was lost from main

### Configuration files (`.changeset/config.json`, `tsconfig.json`, etc.)
Compare what `main` had in the conflicted files against what we kept:

- Prefer `next` unless `main` has a clear fix that should be forward-ported.
```bash
# List files that were modified on both branches (potential conflict sites)
git diff --name-only origin/next...origin/main -- '*.json' '*.yaml' '*.yml'
```

## Steps
For each file, compare the `main` version to the current version:

```bash
git diff origin/main -- <file>
```

Look for:

- **New dependencies** added on `main` that are missing from `next` — these should be added
- **Dependency version bumps** on `main` that are higher than what's on `next` — these should typically be accepted (they're patches/minors)
- **New scripts or config entries** added on `main` — these should be forward-ported
- **Version fields** (`"version":`) — keep `next`'s pre-release versions, do NOT use `main`'s stable versions

### Step 3: Apply corrections

If you find changes from `main` that should have been kept:

1. Apply those specific changes to the current files
2. Run `pnpm install --no-frozen-lockfile` if you modified any `package.json` files
3. `git add` the modified files

### Step 4: Do NOT commit

1. Run `git diff --name-only --diff-filter=U` to list all conflicted files.
2. For each conflicted file, read the file and resolve the conflict following the strategy above.
3. After resolving each file, run `git add <file>` to mark it as resolved.
4. After all files are resolved, verify no conflict markers remain: `grep -r "<<<<<<< " --include="*.ts" --include="*.js" --include="*.json" --include="*.yaml" --include="*.yml" --include="*.md" .`
5. Do NOT commit — the orchestrator will handle committing.
The orchestrator will handle committing.

## Output

Return the list of files that were resolved and whether all conflicts were successfully handled.
Return whether the conflict resolutions were correct and what files (if any) needed corrections.
55 changes: 26 additions & 29 deletions .flue/workflows/merge-fix/WORKFLOW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,25 @@ export const args = v.object({
export default async function mergeFix(flue: FlueClient, { prNumber }: v.InferOutput<typeof args>) {
const branch = 'ci/merge-main-to-next';

// Step 1: Check for merge conflicts (unresolved conflict markers in files)
const conflictCheck = await flue.shell(
'git diff --check HEAD 2>&1 || grep -r "<<<<<<< " --include="*.ts" --include="*.js" --include="*.json" --include="*.yaml" --include="*.yml" --include="*.md" --include="*.mjs" --include="*.cjs" . 2>/dev/null | head -20',
);
const hasConflicts = conflictCheck.stdout.includes('<<<<<<<');

// Step 2: Resolve conflicts if any
if (hasConflicts) {
await flue.skill('merge/resolve-conflicts.md', {
args: { prNumber, branch },
result: v.object({
resolved: v.pipe(
v.boolean(),
v.description('true if all merge conflicts were resolved successfully'),
),
filesResolved: v.pipe(
v.array(v.string()),
v.description('List of files where conflicts were resolved'),
),
}),
});
}
// Step 1: Verify conflict resolutions and resolve any remaining source code conflicts.
// JSON/YAML conflicts were pre-stripped by the GitHub Action (keeping next side).
// This skill checks that nothing important from main was lost, and resolves
// any remaining conflict markers in .ts/.js/.md/.astro files.
const verifyResult = await flue.skill('merge/resolve-conflicts.md', {
args: { prNumber, branch },
result: v.object({
correct: v.pipe(
v.boolean(),
v.description('true if all conflict resolutions were correct or have been fixed'),
),
correctedFiles: v.pipe(
v.array(v.string()),
v.description('List of files that needed corrections after verification'),
),
}),
});

// Step 3: Remove stale changesets that were already released on main
// Step 2: Remove stale changesets that were already released on main
await flue.skill('merge/clean-changesets.md', {
args: { prNumber },
result: v.object({
Expand All @@ -60,7 +55,7 @@ export default async function mergeFix(flue: FlueClient, { prNumber }: v.InferOu
}),
});

// Step 4: Run tests and fix failures
// Step 3: Run tests and fix failures
const fixResult = await flue.skill('merge/fix-tests.md', {
args: { prNumber },
result: v.object({
Expand All @@ -78,13 +73,13 @@ export default async function mergeFix(flue: FlueClient, { prNumber }: v.InferOu
}),
});

// Step 5: Commit and push all changes
// Step 4: Commit and push all changes
const status = await flue.shell('git status --porcelain');
if (status.stdout.trim()) {
await flue.shell('git add -A');

const commitParts = [];
if (hasConflicts) commitParts.push('resolve merge conflicts');
if (verifyResult.correctedFiles.length > 0) commitParts.push('fix merge conflict resolutions');
if (fixResult.fixedFiles.length > 0) commitParts.push('fix test failures');
const commitMsg =
commitParts.length > 0
Expand All @@ -100,9 +95,11 @@ export default async function mergeFix(flue: FlueClient, { prNumber }: v.InferOu
}
}

// Step 6: Post a summary comment on the PR
// Step 5: Post a summary comment on the PR
const summaryParts = [];
if (hasConflicts) summaryParts.push('- Resolved merge conflicts');
if (verifyResult.correctedFiles.length > 0) {
summaryParts.push(`- Fixed conflict resolutions in: ${verifyResult.correctedFiles.join(', ')}`);
}
if (fixResult.fixedFiles.length > 0) {
summaryParts.push(`- Fixed test failures in: ${fixResult.fixedFiles.join(', ')}`);
}
Expand Down Expand Up @@ -134,7 +131,7 @@ ${fixResult.testsPass ? 'All tests pass — this PR should be ready for review.'
return {
pushed: true,
testsPass: fixResult.testsPass,
hasConflicts,
correctedFiles: verifyResult.correctedFiles,
remainingFailures: fixResult.remainingFailures,
};
}
34 changes: 31 additions & 3 deletions .github/workflows/merge-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ on:

env:
IMAGE: ghcr.io/${{ github.repository }}/flue-sandbox
PNPM_STORE_DIR: .pnpm-store

concurrency:
group: merge-fix
Expand Down Expand Up @@ -91,6 +90,37 @@ jobs:
echo "skip=false" >> "$GITHUB_OUTPUT"
fi

- name: Strip conflict markers from JSON/YAML files
if: steps.pr.outputs.number != '' && steps.attempts.outputs.skip != 'true'
# Merge conflicts in package.json files make pnpm install impossible.
# Strip conflict markers (keeping "ours"/next side) so pnpm can parse
# the workspace. The Flue verify skill will check via git diff whether
# anything important from main was lost and patch it back in.
run: |
node -e '
const fs = require("fs");
const path = require("path");
let count = 0;
function fix(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
fix(full);
} else if (/\.(json|yaml|yml)$/.test(entry.name)) {
let c = fs.readFileSync(full, "utf8");
if (c.includes("<<<<<<<")) {
c = c.replace(/^<{7}.*\n([\s\S]*?)^={7}\n[\s\S]*?^>{7}.*\n/gm, "$1");
fs.writeFileSync(full, c);
console.log("Stripped conflicts:", full);
count++;
}
}
}
}
fix(".");
console.log(count + " file(s) fixed");
'

- name: Setup PNPM
if: steps.pr.outputs.number != '' && steps.attempts.outputs.skip != 'true'
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
Expand All @@ -104,8 +134,6 @@ jobs:

- name: Install deps
if: steps.pr.outputs.number != '' && steps.attempts.outputs.skip != 'true'
# Use --no-frozen-lockfile because the merge may have introduced
# lockfile conflicts or new dependencies that need resolving
run: pnpm install --no-frozen-lockfile

- name: Build
Expand Down
Loading
Loading