@next-friday/create-app 2.1.7 → 2.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/templates/base/.claude/settings.json +1 -1
- package/templates/base/.github/workflows/deploy.yml +3 -1
- package/templates/nestjs/AGENTS.md +1 -1
- package/templates/nestjs/README.md +1 -1
- package/templates/nextjs/AGENTS.md +1 -1
- package/templates/nextjs/README.md +1 -1
- package/templates/nodejs/AGENTS.md +1 -1
- package/templates/nodejs/README.md +1 -1
- package/templates/payload/AGENTS.md +1 -1
- package/templates/payload/README.md +1 -1
- package/templates/turborepo/.github/workflows/ci.yml +20 -8
- package/templates/turborepo/.github/workflows/deploy.yml +4 -2
- package/templates/turborepo/AGENTS.md +2 -2
- package/templates/turborepo/README.md +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ The name must:
|
|
|
65
65
|
## What the CLI does
|
|
66
66
|
|
|
67
67
|
1. Copies the template into the project directory and replaces the template's package name with the project name.
|
|
68
|
-
2. Writes `.env` from `.env.example`. For Payload, it sets `PAYLOAD_SECRET` to a random secret.
|
|
68
|
+
2. Writes `.env` from `.env.example`. For Payload and Turborepo, it sets `PAYLOAD_SECRET` to a random secret.
|
|
69
69
|
3. Runs `git init --initial-branch=main`, unless the directory is already in a Git repository.
|
|
70
70
|
4. Runs `pnpm install`, which also installs the Git hooks.
|
|
71
71
|
5. Prints the next steps, for example:
|
|
@@ -75,7 +75,7 @@ The name must:
|
|
|
75
75
|
pnpm start:dev
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
The development script is `pnpm dev` for Next.js and
|
|
78
|
+
The development script is `pnpm dev` for Next.js, Payload, and Turborepo, and `pnpm start:dev` for Node.js and NestJS.
|
|
79
79
|
|
|
80
80
|
Then follow **After creating a project from this template** in the project's `README.md` to make the first commit and set up the repository.
|
|
81
81
|
|
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@ concurrency:
|
|
|
33
33
|
jobs:
|
|
34
34
|
verify:
|
|
35
35
|
name: Verify the requested commit
|
|
36
|
+
if: github.ref == 'refs/heads/main'
|
|
36
37
|
runs-on: ubuntu-latest
|
|
37
38
|
timeout-minutes: 5
|
|
38
39
|
permissions:
|
|
@@ -66,13 +67,14 @@ jobs:
|
|
|
66
67
|
prod)
|
|
67
68
|
previous=uat
|
|
68
69
|
export EXPECTED_TITLE="Deploy $COMMIT_SHA to uat"
|
|
69
|
-
deployed="$(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?event=workflow_dispatch&status=success&per_page=100" --jq '.workflow_runs[] | select(.display_title == env.EXPECTED_TITLE) | .id' | wc -l)"
|
|
70
|
+
deployed="$(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?event=workflow_dispatch&status=success&branch=main&per_page=100" --jq '.workflow_runs[] | select(.display_title == env.EXPECTED_TITLE) | .id' | wc -l)"
|
|
70
71
|
;;
|
|
71
72
|
esac
|
|
72
73
|
[[ "$deployed" -gt 0 ]] || { echo "::error::$COMMIT_SHA has no successful $previous deployment; promote through $previous first"; exit 1; }
|
|
73
74
|
|
|
74
75
|
deploy:
|
|
75
76
|
name: Deploy to ${{ inputs.environment }}
|
|
77
|
+
if: github.ref == 'refs/heads/main'
|
|
76
78
|
needs: verify
|
|
77
79
|
runs-on: ubuntu-latest
|
|
78
80
|
timeout-minutes: 30
|
|
@@ -28,7 +28,7 @@ NestJS HTTP API in TypeScript on pnpm and Node.js `>=24.15.0 <25`.
|
|
|
28
28
|
|
|
29
29
|
## Known pitfalls
|
|
30
30
|
|
|
31
|
-
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that
|
|
31
|
+
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
|
|
32
32
|
|
|
33
33
|
## Related documentation
|
|
34
34
|
|
|
@@ -68,7 +68,7 @@ On Vercel, the zero-configuration NestJS preset takes precedence over the `Docke
|
|
|
68
68
|
- the `RAILWAY_SERVICE` variable: the service name;
|
|
69
69
|
- the `APP_URL` variable: the public `https://` URL.
|
|
70
70
|
|
|
71
|
-
Limit `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
71
|
+
Limit `dev`, `uat`, and `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
72
72
|
|
|
73
73
|
3. Set the repository variable `DEPLOY_ENABLED` to `true`. Each push to `main` that passes CI then deploys to `dev`.
|
|
74
74
|
4. Promote with **Actions → Deploy → Run workflow**, giving the environment and the full commit SHA. The workflow requires a successful CI run on `main` for that commit and a successful deployment to the previous environment, then waits for `/health`.
|
|
@@ -29,7 +29,7 @@ Next.js App Router web app with React and Tailwind CSS, in TypeScript on pnpm an
|
|
|
29
29
|
## Known pitfalls
|
|
30
30
|
|
|
31
31
|
- **First end-to-end run**: run `pnpm exec playwright install chromium` once. `pnpm test:e2e` starts the development server unless one is already running.
|
|
32
|
-
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that
|
|
32
|
+
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
|
|
33
33
|
|
|
34
34
|
## Related documentation
|
|
35
35
|
|
|
@@ -64,7 +64,7 @@ On Vercel, deploy without the image; the Next.js preset takes precedence over th
|
|
|
64
64
|
- the `RAILWAY_SERVICE` variable: the service name;
|
|
65
65
|
- the `APP_URL` variable: the public `https://` URL.
|
|
66
66
|
|
|
67
|
-
Limit `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
67
|
+
Limit `dev`, `uat`, and `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
68
68
|
|
|
69
69
|
3. Set the repository variable `DEPLOY_ENABLED` to `true`. Each push to `main` that passes CI then deploys to `dev`.
|
|
70
70
|
4. Promote with **Actions → Deploy → Run workflow**, giving the environment and the full commit SHA. The workflow requires a successful CI run on `main` for that commit and a successful deployment to the previous environment, then waits for `/health`.
|
|
@@ -26,7 +26,7 @@ TypeScript HTTP service on `node:http`, without a framework, on pnpm and Node.js
|
|
|
26
26
|
|
|
27
27
|
## Known pitfalls
|
|
28
28
|
|
|
29
|
-
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that
|
|
29
|
+
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
|
|
30
30
|
|
|
31
31
|
## Related documentation
|
|
32
32
|
|
|
@@ -64,7 +64,7 @@ docker run --env PORT=3000 --publish 3000:3000 app
|
|
|
64
64
|
- the `RAILWAY_SERVICE` variable: the service name;
|
|
65
65
|
- the `APP_URL` variable: the public `https://` URL.
|
|
66
66
|
|
|
67
|
-
Limit `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
67
|
+
Limit `dev`, `uat`, and `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
68
68
|
|
|
69
69
|
3. Set the repository variable `DEPLOY_ENABLED` to `true`. Each push to `main` that passes CI then deploys to `dev`.
|
|
70
70
|
4. Promote with **Actions → Deploy → Run workflow**, giving the environment and the full commit SHA. The workflow requires a successful CI run on `main` for that commit and a successful deployment to the previous environment, then waits for `/health`.
|
|
@@ -32,7 +32,7 @@ Payload CMS on Next.js App Router and PostgreSQL, in TypeScript on pnpm and Node
|
|
|
32
32
|
## Known pitfalls
|
|
33
33
|
|
|
34
34
|
- **Database for `pnpm dev` and end-to-end tests**: both need a PostgreSQL database in `DATABASE_URL` and `PAYLOAD_SECRET` in `.env`; the README lists every variable. Run `pnpm exec playwright install chromium` once before the first `pnpm test:e2e`.
|
|
35
|
-
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that
|
|
35
|
+
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
|
|
36
36
|
|
|
37
37
|
## Related documentation
|
|
38
38
|
|
|
@@ -88,7 +88,7 @@ On Vercel, deploy without the image; the Next.js preset takes precedence over th
|
|
|
88
88
|
- the `RAILWAY_SERVICE` variable: the service name;
|
|
89
89
|
- the `APP_URL` variable: the public `https://` URL.
|
|
90
90
|
|
|
91
|
-
Limit `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
91
|
+
Limit `dev`, `uat`, and `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
92
92
|
|
|
93
93
|
3. Set the repository variable `DEPLOY_ENABLED` to `true`. Each push to `main` that passes CI then deploys to `dev`.
|
|
94
94
|
4. Promote with **Actions → Deploy → Run workflow**, giving the environment and the full commit SHA. The workflow requires a successful CI run on `main` for that commit and a successful deployment to the previous environment, then waits for `/health`.
|
|
@@ -214,37 +214,46 @@ jobs:
|
|
|
214
214
|
done
|
|
215
215
|
} >> "$GITHUB_OUTPUT"
|
|
216
216
|
- name: Lint Dockerfile
|
|
217
|
+
env:
|
|
218
|
+
AFFECTED_APP: ${{ steps.affected.outputs.app }}
|
|
219
|
+
AFFECTED_BACKOFFICE: ${{ steps.affected.outputs.backoffice }}
|
|
217
220
|
run: |
|
|
218
221
|
curl --silent --show-error --fail --location --output hadolint \
|
|
219
222
|
"https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-linux-x86_64"
|
|
220
223
|
echo "${HADOLINT_SHA256} hadolint" | sha256sum --check --strict
|
|
221
224
|
chmod +x hadolint
|
|
222
225
|
files=()
|
|
223
|
-
if [[ "$
|
|
226
|
+
if [[ "$AFFECTED_APP" == "true" ]]; then
|
|
224
227
|
files+=(apps/app/Dockerfile)
|
|
225
228
|
fi
|
|
226
|
-
if [[ "$
|
|
229
|
+
if [[ "$AFFECTED_BACKOFFICE" == "true" ]]; then
|
|
227
230
|
files+=(apps/backoffice/Dockerfile)
|
|
228
231
|
fi
|
|
229
232
|
if [[ "${#files[@]}" -gt 0 ]]; then
|
|
230
233
|
./hadolint "${files[@]}"
|
|
231
234
|
fi
|
|
232
235
|
- name: Build images
|
|
236
|
+
env:
|
|
237
|
+
AFFECTED_APP: ${{ steps.affected.outputs.app }}
|
|
238
|
+
AFFECTED_BACKOFFICE: ${{ steps.affected.outputs.backoffice }}
|
|
233
239
|
run: |
|
|
234
|
-
if [[ "$
|
|
240
|
+
if [[ "$AFFECTED_APP" == "true" ]]; then
|
|
235
241
|
docker build --file apps/app/Dockerfile --tag app:ci .
|
|
236
242
|
fi
|
|
237
|
-
if [[ "$
|
|
243
|
+
if [[ "$AFFECTED_BACKOFFICE" == "true" ]]; then
|
|
238
244
|
docker build --file apps/backoffice/Dockerfile --tag backoffice:ci .
|
|
239
245
|
fi
|
|
240
246
|
- name: Smoke test images
|
|
247
|
+
env:
|
|
248
|
+
AFFECTED_APP: ${{ steps.affected.outputs.app }}
|
|
249
|
+
AFFECTED_BACKOFFICE: ${{ steps.affected.outputs.backoffice }}
|
|
241
250
|
id: smoke
|
|
242
251
|
run: |
|
|
243
|
-
if [[ "$
|
|
252
|
+
if [[ "$AFFECTED_APP" == "true" ]]; then
|
|
244
253
|
docker run --detach --name app --env PORT=3000 --publish 3000:3000 app:ci
|
|
245
254
|
curl --silent --show-error --fail --retry 15 --retry-delay 1 --retry-all-errors --output /dev/null http://localhost:3000/health
|
|
246
255
|
fi
|
|
247
|
-
if [[ "$
|
|
256
|
+
if [[ "$AFFECTED_BACKOFFICE" == "true" ]]; then
|
|
248
257
|
docker run --detach --name backoffice --env PORT=3001 --env DATABASE_URL=postgres://build-only@localhost/build-only --env PAYLOAD_SECRET=ci-only-secret --env APP_URL=http://localhost:3001 --publish 3001:3001 backoffice:ci
|
|
249
258
|
curl --silent --show-error --fail --retry 15 --retry-delay 1 --retry-all-errors --output /dev/null http://localhost:3001/health
|
|
250
259
|
fi
|
|
@@ -258,16 +267,19 @@ jobs:
|
|
|
258
267
|
docker logs backoffice
|
|
259
268
|
fi
|
|
260
269
|
- name: Scan images for vulnerabilities
|
|
270
|
+
env:
|
|
271
|
+
AFFECTED_APP: ${{ steps.affected.outputs.app }}
|
|
272
|
+
AFFECTED_BACKOFFICE: ${{ steps.affected.outputs.backoffice }}
|
|
261
273
|
run: |
|
|
262
274
|
archive="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
|
|
263
275
|
curl --silent --show-error --fail --location --output "$archive" \
|
|
264
276
|
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/${archive}"
|
|
265
277
|
echo "${TRIVY_SHA256} ${archive}" | sha256sum --check --strict
|
|
266
278
|
tar --extract --gzip --file "$archive" trivy
|
|
267
|
-
if [[ "$
|
|
279
|
+
if [[ "$AFFECTED_APP" == "true" ]]; then
|
|
268
280
|
./trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed --no-progress app:ci
|
|
269
281
|
fi
|
|
270
|
-
if [[ "$
|
|
282
|
+
if [[ "$AFFECTED_BACKOFFICE" == "true" ]]; then
|
|
271
283
|
./trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed --no-progress backoffice:ci
|
|
272
284
|
fi
|
|
273
285
|
|
|
@@ -33,6 +33,7 @@ concurrency:
|
|
|
33
33
|
jobs:
|
|
34
34
|
verify:
|
|
35
35
|
name: Verify the requested commit
|
|
36
|
+
if: github.ref == 'refs/heads/main'
|
|
36
37
|
runs-on: ubuntu-latest
|
|
37
38
|
timeout-minutes: 5
|
|
38
39
|
permissions:
|
|
@@ -66,13 +67,14 @@ jobs:
|
|
|
66
67
|
prod)
|
|
67
68
|
previous=uat
|
|
68
69
|
export EXPECTED_TITLE="Deploy $COMMIT_SHA to uat"
|
|
69
|
-
deployed="$(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?event=workflow_dispatch&status=success&per_page=100" --jq '.workflow_runs[] | select(.display_title == env.EXPECTED_TITLE) | .id' | wc -l)"
|
|
70
|
+
deployed="$(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?event=workflow_dispatch&status=success&branch=main&per_page=100" --jq '.workflow_runs[] | select(.display_title == env.EXPECTED_TITLE) | .id' | wc -l)"
|
|
70
71
|
;;
|
|
71
72
|
esac
|
|
72
73
|
[[ "$deployed" -gt 0 ]] || { echo "::error::$COMMIT_SHA has no successful $previous deployment; promote through $previous first"; exit 1; }
|
|
73
74
|
|
|
74
75
|
deploy:
|
|
75
76
|
name: Deploy to ${{ inputs.environment }}
|
|
77
|
+
if: github.ref == 'refs/heads/main'
|
|
76
78
|
needs: verify
|
|
77
79
|
runs-on: ubuntu-latest
|
|
78
80
|
timeout-minutes: 40
|
|
@@ -134,7 +136,7 @@ jobs:
|
|
|
134
136
|
latest="$completed"
|
|
135
137
|
previous="$candidate"
|
|
136
138
|
fi
|
|
137
|
-
done < <(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?status=success&per_page=50" --jq '.workflow_runs[] | [.id, .display_title] | @tsv')
|
|
139
|
+
done < <(gh api --paginate "repos/$REPOSITORY/actions/workflows/deploy.yml/runs?status=success&branch=main&per_page=50" --jq '.workflow_runs[] | [.id, .display_title] | @tsv')
|
|
138
140
|
while IFS=$'\t' read -r run_id head_sha; do
|
|
139
141
|
[[ -z "$run_id" || "$head_sha" == "$COMMIT_SHA" ]] && continue
|
|
140
142
|
completed="$(gh api "repos/$REPOSITORY/actions/runs/$run_id/jobs" | jq -r --arg env "$RAILWAY_ENVIRONMENT" '[.jobs[] | select(.conclusion == "success" and .name == "Deploy to \($env) / Deploy to \($env)") | .completed_at] | max // empty')"
|
|
@@ -34,8 +34,8 @@ Turborepo workspace in TypeScript on pnpm and Node.js `>=24.22.1 <25`. `apps/app
|
|
|
34
34
|
## Known pitfalls
|
|
35
35
|
|
|
36
36
|
- **Next.js docs live per app**: this Next.js version differs from your training data. Read the guide in `apps/app/node_modules/next/dist/docs/` or `apps/backoffice/node_modules/next/dist/docs/` before writing Next.js code; the workspace root has no `next` package.
|
|
37
|
-
- **Database for `pnpm dev` and end-to-end tests**: the backoffice needs a PostgreSQL database in `DATABASE_URL` and `PAYLOAD_SECRET` in `.env`; the README lists every variable. Run `pnpm exec playwright install chromium` once before the first `pnpm test:e2e`.
|
|
38
|
-
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that
|
|
37
|
+
- **Database for `pnpm dev` and end-to-end tests**: the backoffice needs a PostgreSQL database in `DATABASE_URL` and `PAYLOAD_SECRET` in `.env`; the README lists every variable. Run `pnpm --filter ./apps/app exec playwright install chromium` once before the first `pnpm test:e2e`.
|
|
38
|
+
- **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
|
|
39
39
|
|
|
40
40
|
## Related documentation
|
|
41
41
|
|
|
@@ -94,7 +94,7 @@ On Vercel, deploy an app without its image. The Next.js preset takes precedence
|
|
|
94
94
|
- the `APP_URL` variable: the public Next.js `https://` URL;
|
|
95
95
|
- the `BACKOFFICE_URL` variable: the public backoffice `https://` URL.
|
|
96
96
|
|
|
97
|
-
Limit `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
97
|
+
Limit `dev`, `uat`, and `prod` to the `main` branch and add required reviewers. Environment secrets and variables in a private repository need GitHub Pro, Team, or Enterprise; required reviewers in a private repository need GitHub Enterprise.
|
|
98
98
|
|
|
99
99
|
3. Set the repository variable `DEPLOY_ENABLED` to `true`. Each push to `main` that passes CI then deploys to `dev`. The workflow compares the commit with the last GitHub deployment to that environment and runs `railway up` only for services whose packages changed. A promotion through `uat` or `prod` uses the same comparison against the commit last deployed there, so several commits still ship every changed service. The first deploy to an environment ships both services.
|
|
100
100
|
4. Promote with **Actions → Deploy → Run workflow**, giving the environment and the full commit SHA. The workflow requires a successful CI run on `main` for that commit and a successful deployment to the previous environment, then waits for `/health` on each service it uploaded.
|