@hearthlog/tooling 0.1.0 → 0.1.1

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/bin/hearthlog.mjs CHANGED
@@ -41,6 +41,15 @@ if (deployTools[command]) {
41
41
  process.exit(built === 0 ? (spawnSync(process.execPath, [tsx, source(deployTools[command]), ...rest], { stdio: 'inherit', env }).status ?? 1) : built);
42
42
  }
43
43
 
44
+ // The plan reads the site's generated files too: build them first (a no-op when they are current). `apply` does not,
45
+ // because `apply --skip-build` deploys the release already in place and must not rewrite it.
46
+ if (command === 'plan') {
47
+ const site = rest[rest.indexOf('--site') + 1];
48
+ const env = { ...process.env, ...(rest.includes('--site') && site ? { VITE_STOR_TENANT: site } : {}) };
49
+ const built = spawnSync(process.execPath, [tsx, source('generate/build-generated.ts'), '--quiet'], { stdio: 'inherit', env }).status ?? 1;
50
+ if (built !== 0) process.exit(built);
51
+ }
52
+
44
53
  const entry = {
45
54
  build: 'generate/build-generated.ts',
46
55
  init: 'init/init.ts',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hearthlog/tooling",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "tsx": "^4.23.15",
31
- "@hearthlog/contracts": "0.1.0"
31
+ "@hearthlog/contracts": "0.1.1"
32
32
  },
33
33
  "bin": {
34
34
  "hearthlog": "./bin/hearthlog.mjs"
@@ -155,6 +155,7 @@ export function exportModule(modulesDirectory: string, name: string, out: string
155
155
  writeFileSync(packagePath, `${JSON.stringify(publishable, null, 2)}\n`);
156
156
  mkdirSync(join(out, ".github", "workflows"), { recursive: true });
157
157
  copyFileSync(join(TEMPLATE, "gitignore.tmpl"), join(out, ".gitignore"));
158
+ copyFileSync(join(TEMPLATE, "gitleaks.toml.tmpl"), join(out, ".gitleaks.toml"));
158
159
  // vitest's esbuild needs its install script; pnpm 10 asks for it by name.
159
160
  writeFileSync(join(out, "pnpm-workspace.yaml"), "onlyBuiltDependencies:\n - esbuild\n");
160
161
  copyFileSync(join(TEMPLATE, "ci.yml.tmpl"), join(out, ".github", "workflows", "ci.yml"));
package/src/init/init.ts CHANGED
@@ -80,7 +80,8 @@ export function renderSite(options: InitOptions): Array<[string, string]> {
80
80
  const manifest = JSON.parse(readFileSync(join(TEMPLATE, "package.json.tmpl"), "utf8")) as Record<string, unknown>;
81
81
  const dependencies: Record<string, string> = Object.fromEntries([
82
82
  ...CORE_PACKAGES.map((name) => [`@hearthlog/${name}`, own]),
83
- ...modules.map(({ manifest: { package: name } }) => [name, own]),
83
+ // A module is released on its own version, not on the platform's.
84
+ ...modules.map(({ manifest: { package: name }, directory }) => [name, workspace ? own : `^${(JSON.parse(readFileSync(join(directory, "package.json"), "utf8")) as { version: string }).version}`]),
84
85
  ["@hearthlog/generated", "link:.generated"],
85
86
  ].sort(([a], [b]) => a!.localeCompare(b!)));
86
87
  const devDependencies = Object.fromEntries(Object.entries(tooling.peerDependencies ?? {}).filter(([name]) => !name.startsWith("@hearthlog/")).sort(([a], [b]) => a.localeCompare(b)));
@@ -34,6 +34,11 @@ const SAFE_NOREPLY = /^(?:noreply@github\.com|[0-9]*\+?[a-z0-9-]+@users\.noreply
34
34
 
35
35
  /** Every file under the directory except `.git`, as relative paths. */
36
36
  export function listFiles(directory: string): string[] {
37
+ // In a repository, what could be pushed is what git tracks or would add: an ignored `node_modules` is not part of it.
38
+ if (existsSync(join(directory, ".git"))) {
39
+ const listed = execFileSync("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], { cwd: directory, maxBuffer: 256 * 1024 * 1024 });
40
+ return [...new Set(listed.toString("utf8").split("\0").filter(Boolean))].filter((file) => existsSync(join(directory, file)));
41
+ }
37
42
  const files: string[] = [];
38
43
  const walk = (current: string) => {
39
44
  for (const entry of readdirSync(current, { withFileTypes: true })) {
@@ -0,0 +1,11 @@
1
+ title = "hearthlog"
2
+
3
+ [extend]
4
+ useDefault = true
5
+
6
+ # Entity definitions name the fields of an event payload (`payloadKey: "caloriesPer100g"`); a field name that ends in
7
+ # digits and a letter looks like a key to the generic rule, but it is not a credential.
8
+ [[allowlists]]
9
+ description = "payloadKey names a payload field"
10
+ regexTarget = "line"
11
+ regexes = ['''payloadKey:\s*["'][A-Za-z0-9_]+["']''']
@@ -38,8 +38,6 @@ jobs:
38
38
  cache: pnpm
39
39
  - name: Install dependencies
40
40
  run: pnpm install --frozen-lockfile
41
- - name: Plan (read-only)
42
- run: pnpm exec hearthlog plan --site {{id}}
43
41
  - name: Build and seal
44
42
  env:
45
43
  VITE_STOR_TENANT: {{id}}
@@ -48,6 +46,9 @@ jobs:
48
46
  pnpm exec hearthlog gallery-public:build --site {{id}}
49
47
  pnpm exec vite build
50
48
  pnpm exec hearthlog artifact manifest --site {{id}}
49
+ # After the build: the plan reads the generated files the build writes.
50
+ - name: Plan (read-only)
51
+ run: pnpm exec hearthlog plan --site {{id}}
51
52
  - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
52
53
  with:
53
54
  name: release