@clubedge/create-clubedge-app 0.1.3 → 0.1.9
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/CHANGELOG.md +30 -0
- package/README.md +70 -8
- package/bin/create.mjs +84 -8
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `create-clubedge-app` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.1.9
|
|
6
|
+
|
|
7
|
+
- Use npm Trusted Publishing with GitHub Actions OIDC for releases.
|
|
8
|
+
- Use an npm CLI version supported by Trusted Publishing and remove the token-based publish dependency.
|
|
9
|
+
|
|
10
|
+
## 0.1.8
|
|
11
|
+
|
|
12
|
+
- Correct the pinned Starter commit to the commit actually resolved by the immutable `v0.1.1` tag.
|
|
13
|
+
|
|
14
|
+
## 0.1.7
|
|
15
|
+
|
|
16
|
+
- Pin the default Starter reference to the tested `v0.1.1` release, including the corrected browser contract.
|
|
17
|
+
|
|
18
|
+
## 0.1.6
|
|
19
|
+
|
|
20
|
+
- Move the CLI and Starter repository references to the `Clubedge` GitHub organization.
|
|
21
|
+
- Update package metadata, documentation, tests, and generated provenance for the organization repositories.
|
|
22
|
+
|
|
23
|
+
## 0.1.5
|
|
24
|
+
|
|
25
|
+
- Verify the default Starter tag resolves to its expected commit and record that commit in generated metadata.
|
|
26
|
+
- Add a post-publish smoke-test workflow for the published npm package.
|
|
27
|
+
|
|
28
|
+
## 0.1.4
|
|
29
|
+
|
|
30
|
+
- Pin the default Starter reference to the tested release tag `v0.1.0`.
|
|
31
|
+
- Record the CLI version and Starter reference in generated project metadata and documentation.
|
|
32
|
+
- Add scheduled compatibility verification for the latest Starter `main` branch.
|
|
33
|
+
- Document the CLI-to-Starter version relationship and release workflow.
|
|
34
|
+
|
|
5
35
|
## 0.1.3
|
|
6
36
|
|
|
7
37
|
- Keep generated project-name customization aligned with the dashboard's route-local sidebar.
|
package/README.md
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
# create-clubedge-app
|
|
2
2
|
|
|
3
|
-
[](https://github.com/Clubedge/create-clubedge-app/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
|
|
6
|
-
Create a Next.js application from the [Clubedge Starter](https://github.com/
|
|
6
|
+
Create a Next.js application from the [Clubedge Starter](https://github.com/Clubedge/clubedge-starter) reference implementation.
|
|
7
7
|
|
|
8
|
-
The CLI downloads
|
|
8
|
+
The CLI downloads a tested Starter release, names the generated project, creates `apps/web/.env.local` from the example, initializes Git, and installs dependencies. The Starter remains the source of truth for the generated architecture.
|
|
9
|
+
|
|
10
|
+
## Version relationship
|
|
11
|
+
|
|
12
|
+
Each CLI release is tested against one specific Starter release:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
create-clubedge-app v0.1.9
|
|
16
|
+
|
|
|
17
|
+
v
|
|
18
|
+
Clubedge Starter v0.1.1
|
|
19
|
+
commit 0be0c18d41f01cd011c576fb65c25711081b8ad4
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The current relationship is:
|
|
23
|
+
|
|
24
|
+
| CLI release | Default Starter release | Meaning |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| `create-clubedge-app@0.1.9` | `clubedge-starter@v0.1.1` | The CLI's required, tested default |
|
|
27
|
+
|
|
28
|
+
This means the same CLI version always scaffolds the same Starter revision by default. The CLI does not silently follow Starter `main`.
|
|
29
|
+
|
|
30
|
+
The `v0.1.1` tag is expected to resolve to commit
|
|
31
|
+
`0be0c18d41f01cd011c576fb65c25711081b8ad4`. The CLI verifies this before
|
|
32
|
+
scaffolding with the default reference and fails rather than silently using a
|
|
33
|
+
moved tag.
|
|
34
|
+
|
|
35
|
+
When the Starter changes, its maintainers first publish a new versioned release, such as `v0.2.0`. The CLI is then updated to use that release, all generated-project checks must pass, and a new CLI version is published. This keeps Starter and CLI releases independently versioned while preserving a tested compatibility relationship.
|
|
9
36
|
|
|
10
37
|
## Requirements
|
|
11
38
|
|
|
@@ -46,7 +73,7 @@ pnpm dlx @clubedge/create-clubedge-app
|
|
|
46
73
|
```text
|
|
47
74
|
Usage: pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
48
75
|
|
|
49
|
-
--ref <
|
|
76
|
+
--ref <ref> Select a starter tag, branch, or commit (default: v0.1.1)
|
|
50
77
|
--no-install Skip pnpm install
|
|
51
78
|
--no-git Skip Git initialization
|
|
52
79
|
-h, --help Show help
|
|
@@ -56,15 +83,31 @@ Usage: pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
|
56
83
|
Examples:
|
|
57
84
|
|
|
58
85
|
```sh
|
|
59
|
-
pnpm dlx @clubedge/create-clubedge-app my-app --ref
|
|
86
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref <starter-tag-or-commit>
|
|
60
87
|
pnpm dlx @clubedge/create-clubedge-app my-app --no-install
|
|
61
88
|
```
|
|
62
89
|
|
|
63
|
-
The target directory must be empty or not exist. The CLI will not delete or overwrite files in a non-empty target directory. The default `
|
|
90
|
+
The target directory must be empty or not exist. The CLI will not delete or overwrite files in a non-empty target directory. The default is the tested `v0.1.1` Starter release, so the same CLI version produces the same Starter revision. Use `--ref` to explicitly select a tag, branch, or commit.
|
|
91
|
+
|
|
92
|
+
The default is the tested Starter release tag `v0.1.1`. Every generated project records its CLI version, Starter repository, exact Starter ref, and resolved Starter commit in `package.json` and `README.md`.
|
|
93
|
+
|
|
94
|
+
Use `--ref` only when you intentionally want a different Starter revision:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
# Reproduce the supported default
|
|
98
|
+
pnpm dlx @clubedge/create-clubedge-app my-app
|
|
99
|
+
|
|
100
|
+
# Try an unreleased Starter change
|
|
101
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref main
|
|
102
|
+
|
|
103
|
+
# Reproduce a specific Starter release or commit
|
|
104
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref v0.1.1
|
|
105
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref <commit-sha>
|
|
106
|
+
```
|
|
64
107
|
|
|
65
108
|
## How it works
|
|
66
109
|
|
|
67
|
-
This
|
|
110
|
+
This CLI scaffolds the complete reference Starter. It does not yet offer selectable SaaS, dashboard, or minimal feature presets; those should be added once each preset has a distinct, maintained template. This keeps CLI output aligned with the Starter repository instead of creating a second, drifting copy of its source.
|
|
68
111
|
|
|
69
112
|
## Development
|
|
70
113
|
|
|
@@ -76,7 +119,26 @@ pnpm check
|
|
|
76
119
|
pnpm test
|
|
77
120
|
```
|
|
78
121
|
|
|
79
|
-
CI
|
|
122
|
+
CI scaffolds a clean project from the pinned Starter release, installs its dependencies, runs linting, typechecking, unit tests, browser checks, and a production build, then starts the generated app and checks the landing page, sign-up page, dashboard, health endpoint, logo, and favicon. A scheduled, non-blocking compatibility job also checks Starter `main`.
|
|
123
|
+
|
|
124
|
+
## Release workflow
|
|
125
|
+
|
|
126
|
+
### Starter maintainers
|
|
127
|
+
|
|
128
|
+
1. Make and validate changes in `clubedge-starter`.
|
|
129
|
+
2. Run lint, typecheck, unit tests, browser tests, and production build.
|
|
130
|
+
3. Update the Starter package versions.
|
|
131
|
+
4. Commit `main`, create a release tag such as `v0.2.0`, and publish the Starter release.
|
|
132
|
+
|
|
133
|
+
### CLI maintainers
|
|
134
|
+
|
|
135
|
+
1. Change `defaultStarterRef` in [`bin/create.mjs`](bin/create.mjs) to the new tested Starter tag.
|
|
136
|
+
2. Update the version relationship table and changelog.
|
|
137
|
+
3. Generate a clean project from that exact tag.
|
|
138
|
+
4. Run install, lint, typecheck, unit tests, browser tests, production build, and runtime smoke checks.
|
|
139
|
+
5. Publish a new CLI version only after the generated-project verification passes.
|
|
140
|
+
|
|
141
|
+
The required CI job always tests the pinned default. The scheduled compatibility job tests Starter `main` early, but unreleased Starter changes must not change the stable CLI default.
|
|
80
142
|
|
|
81
143
|
## Contributing
|
|
82
144
|
|
package/bin/create.mjs
CHANGED
|
@@ -8,8 +8,9 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import { pathToFileURL } from "node:url";
|
|
10
10
|
|
|
11
|
-
const starterRepository = "
|
|
12
|
-
const
|
|
11
|
+
const starterRepository = "Clubedge/clubedge-starter";
|
|
12
|
+
const defaultStarterRef = "v0.1.1";
|
|
13
|
+
const defaultStarterCommit = "0be0c18d41f01cd011c576fb65c25711081b8ad4";
|
|
13
14
|
const packageVersion = JSON.parse(
|
|
14
15
|
await readFile(new URL("../package.json", import.meta.url), "utf8"),
|
|
15
16
|
).version;
|
|
@@ -19,12 +20,14 @@ function showHelp() {
|
|
|
19
20
|
create-clubedge-app ${packageVersion}
|
|
20
21
|
|
|
21
22
|
Create a Next.js project from the Clubedge Starter reference repository.
|
|
23
|
+
This CLI release uses Starter ${defaultStarterRef} by default.
|
|
24
|
+
Expected Starter commit: ${defaultStarterCommit}
|
|
22
25
|
|
|
23
26
|
Usage:
|
|
24
27
|
pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
25
28
|
|
|
26
29
|
Options:
|
|
27
|
-
--ref <
|
|
30
|
+
--ref <ref> Starter tag, branch, or commit to scaffold (default: ${defaultStarterRef})
|
|
28
31
|
--no-install Skip dependency installation
|
|
29
32
|
--no-git Skip Git repository initialization
|
|
30
33
|
-h, --help Show this help
|
|
@@ -32,13 +35,16 @@ Options:
|
|
|
32
35
|
|
|
33
36
|
Examples:
|
|
34
37
|
pnpm dlx @clubedge/create-clubedge-app my-app
|
|
35
|
-
pnpm dlx @clubedge/create-clubedge-app my-app --ref
|
|
38
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref <starter-tag-or-commit>
|
|
36
39
|
pnpm dlx @clubedge/create-clubedge-app my-app --no-install
|
|
40
|
+
|
|
41
|
+
Release model:
|
|
42
|
+
CLI ${packageVersion} -> Starter ${defaultStarterRef}
|
|
37
43
|
`);
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
function parseArguments(args) {
|
|
41
|
-
const options = { install: true, git: true, ref:
|
|
47
|
+
const options = { install: true, git: true, ref: defaultStarterRef, projectDirectory: undefined };
|
|
42
48
|
|
|
43
49
|
for (let index = 0; index < args.length; index += 1) {
|
|
44
50
|
const argument = args[index];
|
|
@@ -121,6 +127,57 @@ async function run(command, args, cwd) {
|
|
|
121
127
|
});
|
|
122
128
|
}
|
|
123
129
|
|
|
130
|
+
async function runCapture(command, args, cwd) {
|
|
131
|
+
return await new Promise((resolvePromise, rejectPromise) => {
|
|
132
|
+
const child = spawn(command, args, {
|
|
133
|
+
cwd,
|
|
134
|
+
shell: false,
|
|
135
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
136
|
+
});
|
|
137
|
+
let stdout = "";
|
|
138
|
+
let stderr = "";
|
|
139
|
+
child.stdout.on("data", (chunk) => {
|
|
140
|
+
stdout += chunk;
|
|
141
|
+
});
|
|
142
|
+
child.stderr.on("data", (chunk) => {
|
|
143
|
+
stderr += chunk;
|
|
144
|
+
});
|
|
145
|
+
child.once("error", rejectPromise);
|
|
146
|
+
child.once("exit", (code, signal) => {
|
|
147
|
+
if (code === 0) {
|
|
148
|
+
resolvePromise(stdout.trim());
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
rejectPromise(
|
|
152
|
+
new Error(
|
|
153
|
+
`${command} exited with ${signal ? `signal ${signal}` : `code ${code}`}${
|
|
154
|
+
stderr.trim() ? `: ${stderr.trim()}` : "."
|
|
155
|
+
}`,
|
|
156
|
+
),
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function verifyDefaultStarterReference(starterRef) {
|
|
163
|
+
if (starterRef !== defaultStarterRef) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const remote = `https://github.com/${starterRepository}.git`;
|
|
168
|
+
const resolvedReference = await runCapture("git", [
|
|
169
|
+
"ls-remote",
|
|
170
|
+
remote,
|
|
171
|
+
`refs/tags/${starterRef}^{}`,
|
|
172
|
+
]);
|
|
173
|
+
const resolvedCommit = resolvedReference.split(/\s+/)[0];
|
|
174
|
+
if (resolvedCommit !== defaultStarterCommit) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Starter tag ${starterRef} resolved to ${resolvedCommit || "no commit"}, expected ${defaultStarterCommit}.`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
124
181
|
async function ensureTargetIsSafe(directory) {
|
|
125
182
|
await mkdir(dirname(directory), { recursive: true });
|
|
126
183
|
|
|
@@ -137,10 +194,21 @@ async function ensureTargetIsSafe(directory) {
|
|
|
137
194
|
}
|
|
138
195
|
}
|
|
139
196
|
|
|
140
|
-
async function customizeProject(
|
|
197
|
+
async function customizeProject(
|
|
198
|
+
directory,
|
|
199
|
+
packageName,
|
|
200
|
+
starterRef = defaultStarterRef,
|
|
201
|
+
starterCommit = starterRef === defaultStarterRef ? defaultStarterCommit : undefined,
|
|
202
|
+
) {
|
|
141
203
|
const rootManifestPath = join(directory, "package.json");
|
|
142
204
|
const rootManifest = JSON.parse(await readFile(rootManifestPath, "utf8"));
|
|
143
205
|
rootManifest.name = packageName;
|
|
206
|
+
rootManifest.clubedge = {
|
|
207
|
+
cliVersion: packageVersion,
|
|
208
|
+
starterRepository,
|
|
209
|
+
starterRef,
|
|
210
|
+
...(starterCommit ? { starterCommit } : {}),
|
|
211
|
+
};
|
|
144
212
|
|
|
145
213
|
for (const scriptName of ["docker:build", "docker:start"]) {
|
|
146
214
|
if (rootManifest.scripts?.[scriptName]) {
|
|
@@ -155,7 +223,14 @@ async function customizeProject(directory, packageName) {
|
|
|
155
223
|
const readmePath = join(directory, "README.md");
|
|
156
224
|
const readme = await readFile(readmePath, "utf8");
|
|
157
225
|
const displayName = displayNameFromPackageName(packageName);
|
|
158
|
-
|
|
226
|
+
const starterCommitLine = starterCommit ? `\n- Starter commit: \`${starterCommit}\`` : "";
|
|
227
|
+
const customizedReadme = readme
|
|
228
|
+
.replace(/^# Clubedge Starter$/m, `# ${displayName}`)
|
|
229
|
+
.replace(
|
|
230
|
+
/^# (.+)$/m,
|
|
231
|
+
`$&\n\n## Generated from\n\n- Starter repository: \`${starterRepository}\`\n- Starter ref: \`${starterRef}\`${starterCommitLine}\n- CLI version: \`${packageVersion}\``,
|
|
232
|
+
);
|
|
233
|
+
await writeFile(readmePath, customizedReadme);
|
|
159
234
|
|
|
160
235
|
const layoutPath = join(directory, "apps", "web", "src", "app", "layout.tsx");
|
|
161
236
|
const layout = await readFile(layoutPath, "utf8");
|
|
@@ -227,12 +302,13 @@ async function createProject(options) {
|
|
|
227
302
|
await ensureTargetIsSafe(projectDirectory);
|
|
228
303
|
|
|
229
304
|
const projectName = packageNameFromDirectory(projectDirectory);
|
|
305
|
+
await verifyDefaultStarterReference(options.ref);
|
|
230
306
|
const source = `gh:${starterRepository}#${options.ref}`;
|
|
231
307
|
const downloadSpinner = spinner();
|
|
232
308
|
downloadSpinner.start(`Downloading Clubedge Starter (${options.ref})`);
|
|
233
309
|
try {
|
|
234
310
|
await downloadTemplate(source, { dir: projectDirectory, force: true });
|
|
235
|
-
await customizeProject(projectDirectory, projectName);
|
|
311
|
+
await customizeProject(projectDirectory, projectName, options.ref);
|
|
236
312
|
downloadSpinner.stop("Starter files downloaded and configured");
|
|
237
313
|
} catch (error) {
|
|
238
314
|
downloadSpinner.stop("Project scaffold failed");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clubedge/create-clubedge-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Create a Next.js application from the Clubedge Starter reference implementation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.9.0",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/
|
|
23
|
+
"url": "https://github.com/Clubedge/create-clubedge-app.git"
|
|
24
24
|
},
|
|
25
|
-
"homepage": "https://github.com/
|
|
25
|
+
"homepage": "https://github.com/Clubedge/create-clubedge-app#readme",
|
|
26
26
|
"bugs": {
|
|
27
|
-
"url": "https://github.com/
|
|
27
|
+
"url": "https://github.com/Clubedge/create-clubedge-app/issues"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"create-clubedge-app",
|