Skip to content

Commit 9d2855b

Browse files
committed
Merge remote-tracking branch 'origin/alpha' into fix/2165-content-resource-prerender-hydration
2 parents 4d92e4e + 9135af1 commit 9d2855b

232 files changed

Lines changed: 7543 additions & 3607 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
name: pr-description
3+
description: Generate a pull request description for the current branch.
4+
---
5+
16
Generate a pull request description for the current branch.
27

38
1. Run `git fetch --all` then `git log --oneline $(git merge-base HEAD origin/beta)..HEAD` to see all commits on this branch.

.agents/skills/review-pr.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
name: review-pr
3+
description: Review a pull request for functional concerns. Use as a guide for reviewers or submitters preparing a PR.
4+
---
5+
6+
Review the specified pull request for **functional concerns only**. Ignore stylistic nits that don't impact correctness, performance, or maintainability.
7+
8+
The PR number is provided as an argument. If no argument is given, check for an open PR on the current branch.
9+
10+
## 1. Fetch PR context
11+
12+
- Use `gh pr view <number> --json title,body,headRefName,baseRefName,files,additions,deletions` to get metadata
13+
- Use `gh pr diff <number>` to get the full diff
14+
- Read every changed file in the diff — don't skim
15+
16+
## 2. Review focus areas
17+
18+
Evaluate the diff against these categories. Only report findings that have real functional impact:
19+
20+
| Category | What to look for |
21+
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
22+
| **Logic bugs** | Off-by-one errors, incorrect conditions, unreachable code, silent failures |
23+
| **Type safety** | Unsafe casts, type discrimination holes, `any` leaks, incorrect generics |
24+
| **Regex** | ReDoS potential, incorrect escaping, wrong flags, missing anchors |
25+
| **Performance** | Eager evaluation in hot paths, unnecessary allocations per-request, O(n^2) where O(n) is possible |
26+
| **State & concurrency** | Module-scoped mutable state, race conditions, missing cleanup |
27+
| **Code duplication** | Duplicated logic that will drift — only flag if >50 lines or contains branching logic |
28+
| **API contracts** | Breaking changes not flagged, silent behavior changes, incorrect error handling at boundaries |
29+
| **Security** | Injection vectors, credential handling, unsafe deserialization |
30+
| **Test coverage alignment** | Do the tests actually exercise the code paths that changed, or are they testing something adjacent? |
31+
| **Build artifact impact** | Does the change affect what ships in the npm package? New files in `src/` that aren't tree-shakeable, accidental inclusion of test files, etc. |
32+
33+
## 3. Check contribution guidelines
34+
35+
Read `CONTRIBUTING.md` at the repo root and verify the PR complies. Only check mechanical items:
36+
37+
| Guideline | How to verify |
38+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
39+
| **PR title format** | Must be `type(scope): description`. Type must be one of: build, ci, docs, feat, fix, perf, refactor, style, test. Scope must be a supported package name from CONTRIBUTING.md. |
40+
| **Tests included** | New functionality must have tests. Check the PR body's test plan for unchecked items. |
41+
| **Squash merge** | Preferred unless the PR explains why commit boundaries matter. |
42+
| **Related commits** | All commits should be related. Flag disjoint changes that should be separate PRs. |
43+
| **Linked issues** | The PR should reference related issues. Flag if "Closes #" is empty. |
44+
| **PR template** | Should include affected scope, test plan, and merge strategy recommendation. |
45+
46+
## 4. Output format
47+
48+
Write all findings in **second person**, actionable, ready to post as a review comment.
49+
50+
- Code findings as a flat list grouped by severity
51+
- For each finding:
52+
- Name the category
53+
- Reference the specific file and code
54+
- Explain the functional impact
55+
- Suggest a fix if non-obvious
56+
- Mechanical guideline findings (title format, tests, linked issues, etc.)
57+
58+
Skip categories with no findings. Do not pad the review with praise or filler.
59+
60+
End with a verdict table:
61+
62+
```
63+
| Area | Verdict |
64+
|------|---------|
65+
| ... | ... |
66+
```
67+
68+
Keep verdicts to one phrase: "Clean", "Minor concern", "Should fix before merge", "Blocking".

.dagger/src/index.ts

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@ const DEFAULT_E2E_PROJECTS =
66

77
@object()
88
export class AnalogCi {
9+
private withHeartbeatExec(
10+
ctr: Container,
11+
label: string,
12+
command: string[],
13+
): Container {
14+
return ctr.withExec([
15+
'node',
16+
'tools/scripts/with-heartbeat.mts',
17+
'--label',
18+
label,
19+
'--',
20+
...command,
21+
]);
22+
}
23+
924
private withNxCloudToken(ctr: Container, nxCloudToken?: Secret): Container {
1025
if (!nxCloudToken) {
1126
return ctr;
@@ -15,7 +30,7 @@ export class AnalogCi {
1530
}
1631

1732
private withPlaywrightChromium(ctr: Container): Container {
18-
return ctr.withExec([
33+
return this.withHeartbeatExec(ctr, 'Playwright Chromium install', [
1934
'pnpm',
2035
'exec',
2136
'playwright',
@@ -26,22 +41,27 @@ export class AnalogCi {
2641
}
2742

2843
private withBuildAndVerify(ctr: Container): Container {
29-
return ctr
30-
.withExec([
31-
'pnpm',
32-
'exec',
33-
'nx',
34-
'run-many',
35-
'--target',
36-
'build',
37-
'--all',
38-
])
39-
.withExec(['node', 'tools/scripts/verify-route-freshness.mts'])
40-
.withExec(['pnpm', 'exec', 'nx', 'build-storybook', 'analog-app']);
44+
return this.withHeartbeatExec(
45+
this.withHeartbeatExec(
46+
this.withHeartbeatExec(ctr, 'Nx build run-many', [
47+
'pnpm',
48+
'exec',
49+
'nx',
50+
'run-many',
51+
'--target',
52+
'build',
53+
'--all',
54+
]),
55+
'Route freshness verification',
56+
['node', 'tools/scripts/verify-route-freshness.mts'],
57+
),
58+
'Storybook build',
59+
['pnpm', 'exec', 'nx', 'build-storybook', 'analog-app'],
60+
);
4161
}
4262

4363
private withTestTargets(ctr: Container): Container {
44-
return ctr.withExec([
64+
return this.withHeartbeatExec(ctr, 'Nx test run-many', [
4565
'pnpm',
4666
'exec',
4767
'nx',
@@ -58,7 +78,7 @@ export class AnalogCi {
5878
ctr: Container,
5979
projects = DEFAULT_E2E_PROJECTS,
6080
): Container {
61-
return ctr.withExec([
81+
return this.withHeartbeatExec(ctr, `Nx e2e run-many (${projects})`, [
6282
'pnpm',
6383
'exec',
6484
'nx',
@@ -150,7 +170,16 @@ export class AnalogCi {
150170
.withDirectory('/app', source)
151171
.withWorkdir('/app')
152172
.withMountedCache('/app/.nx/cache', nxCache)
153-
.withExec(['pnpm', 'install', '--frozen-lockfile']);
173+
.withExec([
174+
'node',
175+
'tools/scripts/with-heartbeat.mts',
176+
'--label',
177+
'pnpm install',
178+
'--',
179+
'pnpm',
180+
'install',
181+
'--frozen-lockfile',
182+
]);
154183
}
155184

156185
/** Check formatting via the workspace prettier:check script. */

.github/workflows/ci.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ env:
88
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
99
NX_VERBOSE_LOGGING: ${{ vars.NX_VERBOSE_LOGGING }}
1010
NX_ISOLATE_PLUGINS: 'false'
11+
ANALOG_CI_HEARTBEAT_MS: '30000'
1112

1213
concurrency:
1314
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
@@ -127,11 +128,11 @@ jobs:
127128
cache: 'pnpm'
128129
cache-dependency-path: '**/pnpm-lock.yaml'
129130
- name: Install
130-
run: pnpm install --frozen-lockfile --prefer-offline
131+
run: node tools/scripts/with-heartbeat.mts --label "pnpm install" -- pnpm install --frozen-lockfile --prefer-offline
131132
- name: Build
132-
run: pnpm build
133+
run: node tools/scripts/with-heartbeat.mts --label "pnpm build" -- pnpm build
133134
- name: Verify route freshness
134-
run: node tools/scripts/verify-route-freshness.mts
135+
run: node tools/scripts/with-heartbeat.mts --label "verify route freshness" -- node tools/scripts/verify-route-freshness.mts
135136

136137
build-native-windows:
137138
name: Native / Windows
@@ -158,11 +159,11 @@ jobs:
158159
cache: 'pnpm'
159160
cache-dependency-path: '**/pnpm-lock.yaml'
160161
- name: Install
161-
run: pnpm install --frozen-lockfile --prefer-offline
162+
run: node tools/scripts/with-heartbeat.mts --label "pnpm install" -- pnpm install --frozen-lockfile --prefer-offline
162163
- name: Build
163-
run: pnpm build
164+
run: node tools/scripts/with-heartbeat.mts --label "pnpm build" -- pnpm build
164165
- name: Verify route freshness
165-
run: node tools/scripts/verify-route-freshness.mts
166+
run: node tools/scripts/with-heartbeat.mts --label "verify route freshness" -- node tools/scripts/verify-route-freshness.mts
166167
- name: Verify
167168
run: more dist\apps\blog-app\analog\public\index.html
168169

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,5 @@ vitest.config.*.timestamp*
8181
gradle.properties
8282
.cursor
8383
.claude
84-
gradle.properties
84+
gradle.properties
85+
*.tsbuildinfo

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# [3.0.0-alpha.26](https://github.com/analogjs/analog/compare/v3.0.0-alpha.25...v3.0.0-alpha.26) (2026-04-06)
2+
3+
### Features
4+
5+
- **platform:** add generic style-pipeline hooks for community plugins ([#2245](https://github.com/analogjs/analog/issues/2245)) ([df8971a](https://github.com/analogjs/analog/commit/df8971a50be6f00715a01d3ee66ceea07e3c71f0))
6+
17
# [3.0.0-alpha.25](https://github.com/analogjs/analog/compare/v3.0.0-alpha.24...v3.0.0-alpha.25) (2026-04-05)
28

39
### Bug Fixes

apps/analog-app-e2e/project.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
"cwd": "apps/analog-app-e2e",
1717
"command": "playwright test"
1818
}
19+
},
20+
"typecheck": {
21+
"executor": "nx:run-commands",
22+
"options": {
23+
"cwd": "apps/analog-app-e2e",
24+
"command": "pnpm exec tsgo -p tsconfig.json --noEmit"
25+
}
1926
}
2027
}
2128
}

apps/analog-app/.storybook/main.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { fileURLToPath } from 'node:url';
22
import { dirname } from 'node:path';
33
import type { StorybookConfig } from '@analogjs/storybook-angular';
4+
import { mergeConfig } from 'vite';
45

56
const config: StorybookConfig = {
67
stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'],
@@ -12,6 +13,14 @@ const config: StorybookConfig = {
1213
name: getAbsolutePath('@analogjs/storybook-angular'),
1314
options: {},
1415
},
16+
async viteFinal(config) {
17+
return mergeConfig(config, {
18+
build: {
19+
// Lightning CSS currently chokes on the generated Storybook preview CSS.
20+
cssMinify: 'esbuild',
21+
},
22+
});
23+
},
1524
};
1625

1726
export default config;

apps/analog-app/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
"version": "0.0.0",
55
"dependencies": {
66
"@analogjs/content": "workspace:*",
7+
"@analogjs/my-package": "workspace:*",
78
"@analogjs/router": "workspace:*",
9+
"@analogjs/top-bar": "workspace:*",
810
"es-toolkit": "catalog:"
911
},
1012
"devDependencies": {
1113
"@analogjs/platform": "workspace:*",
1214
"@analogjs/storybook-angular": "workspace:*",
13-
"@analogjs/vite-plugin-angular": "workspace:*"
15+
"@analogjs/vite-plugin-angular": "workspace:*",
16+
"@analogjs/vitest-angular": "workspace:*"
1417
}
1518
}

apps/analog-app/project.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
"targets": {
99
"build": {
1010
"executor": "@nx/vite:build",
11-
"dependsOn": ["platform:build", "router:build"],
11+
"dependsOn": [
12+
"platform:build",
13+
"router:build",
14+
"my-package:build",
15+
"top-bar:build"
16+
],
1217
"outputs": [
1318
"{options.outputPath}",
1419
"{workspaceRoot}/dist/apps/analog-app/.nitro",
@@ -54,7 +59,9 @@
5459
"options": {
5560
"cwd": "dist/apps/analog-app/analog",
5661
"command": "node --unhandled-rejections=throw ./server/index.mjs",
57-
"env": { "PORT": "43000" }
62+
"env": {
63+
"PORT": "43000"
64+
}
5865
},
5966
"dependsOn": ["build"]
6067
},
@@ -98,6 +105,13 @@
98105
"loadPaths": []
99106
}
100107
}
108+
},
109+
"typecheck": {
110+
"executor": "nx:run-commands",
111+
"options": {
112+
"cwd": "apps/analog-app",
113+
"command": "pnpm exec tsgo -p tsconfig.app.json --noEmit"
114+
}
101115
}
102116
}
103117
}

0 commit comments

Comments
 (0)