@zeropress/build-pages 0.5.2 → 0.5.5

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 CHANGED
@@ -1,8 +1,11 @@
1
1
  # @zeropress/build-pages
2
2
 
3
+ ![npm](https://img.shields.io/npm/v/%40zeropress%2Fbuild-pages)
4
+ ![license](https://img.shields.io/npm/l/%40zeropress%2Fbuild-pages)
5
+
3
6
  Build ZeroPress static output for modern hosting platforms.
4
7
 
5
- `@zeropress/build-pages` turns a directory of Markdown files and public assets into a static ZeroPress site. It discovers Markdown pages, prepares the site data, stages public files, and runs `@zeropress/build`.
8
+ `@zeropress/build-pages` turns a directory of Markdown files and public assets into a static ZeroPress site. It discovers Markdown pages, prepares the site data, stages public files, and runs [`@zeropress/build`](https://github.com/zeropress-app/zeropress-build).
6
9
 
7
10
  The generated output is plain static files that can be deployed to GitHub Pages, Cloudflare Pages, Netlify, Vercel, or any static hosting provider.
8
11
 
@@ -97,10 +100,52 @@ jobs:
97
100
 
98
101
  The action `zeropress-build-pages` builds the static files only. Uploading and deploying are handled by your hosting provider's deployment action or CLI.
99
102
 
103
+ Minimal action usage:
104
+
105
+ ```yaml
106
+ - name: Build ZeroPress Pages
107
+ uses: zeropress-app/zeropress-build-pages@v0
108
+ ```
109
+
110
+ That is equivalent to:
111
+
112
+ ```yaml
113
+ - name: Build ZeroPress Pages
114
+ uses: zeropress-app/zeropress-build-pages@v0
115
+ with:
116
+ source: ./docs
117
+ destination: ./_site
118
+ theme: docs
119
+ skip-untitled-markdown: false
120
+ skip-link-check: false
121
+ copy-markdown-source: true
122
+ ```
123
+
124
+ Custom input example:
125
+
126
+ ```yaml
127
+ - name: Build ZeroPress Pages
128
+ uses: zeropress-app/zeropress-build-pages@v0
129
+ with:
130
+ source: ./documents
131
+ destination: ./_site
132
+ theme-path: ./theme-docs
133
+ config: ./documents/.zeropress/config.json
134
+ site-url: https://example.com/docs
135
+ copy-markdown-source: false
136
+ ```
137
+
100
138
  In the action inputs:
101
139
 
102
140
  - `source` is the directory that contains your Markdown pages, public files, and optional `.zeropress/config.json`. The default is `./docs`.
103
141
  - `destination` is the directory where the generated static site is written. The default is `./_site`.
142
+ - `theme` is the bundled theme name. The default is `docs`.
143
+ - `theme-path` is a custom local ZeroPress theme directory. It takes precedence over `theme`.
144
+ - `config` is the config file path. The default is `<source>/.zeropress/config.json`.
145
+ - `site-url` overrides the canonical site URL from config.
146
+ - `skip-untitled-markdown` skips Markdown files without a page title instead of failing. The default is `false`.
147
+ - `skip-link-check` skips internal link checking after build. The default is `false`.
148
+ - `copy-markdown-source` copies original Markdown files to the generated output and enables `View this page as Markdown` links in the bundled docs theme. The default is `true`.
104
149
 
105
150
  For GitHub Pages, the generated `destination` directory can be passed to `actions/upload-pages-artifact`. For Cloudflare Pages, Netlify, Vercel, or another static host, pass the same `destination` directory to that provider's deploy step.
106
151
 
@@ -138,42 +183,37 @@ The CLI requires explicit input and output paths. The GitHub Action keeps safe d
138
183
 
139
184
  | Option | Default | Purpose |
140
185
  | --- | --- | --- |
141
- | `--source <dir>` | required | Source directory containing Markdown and public files |
186
+ | `--source <dir>` | required | Dedicated source directory containing Markdown and public files |
142
187
  | `--destination <dir>` | required | Output directory |
143
188
  | `--theme docs` | `docs` | Bundled docs theme |
144
189
  | `--theme-path <dir>` | none | Custom ZeroPress theme directory |
145
190
  | `--config <path>` | `<source>/.zeropress/config.json` | Build Pages config |
146
191
  | `--site-url <url>` | config `site.url` | Canonical URL override |
147
192
  | `--skip-untitled-markdown` | `false` | Skip Markdown without a page title |
148
- | `--no-check-links` | false | Skip link checking |
149
-
150
- Equivalent environment variables:
151
-
152
- | Env | Maps to |
153
- | --- | --- |
154
- | `ZEROPRESS_PUBLIC_DIR` | `--source` |
155
- | `ZEROPRESS_OUT_DIR` | `--destination` |
156
- | `ZEROPRESS_THEME_DIR` | `--theme-path` |
157
- | `ZEROPRESS_BUILD_PAGES_CONFIG` | `--config` |
158
- | `ZEROPRESS_SITE_URL` | `--site-url` |
159
- | `ZEROPRESS_SKIP_UNTITLED_MARKDOWN=true` | `--skip-untitled-markdown` |
160
-
161
- CLI options take precedence over environment variables.
193
+ | `--skip-link-check` | `false` | Skip link checking |
194
+ | `--no-copy-markdown-source` | `false` | Do not copy original Markdown files to output |
162
195
 
163
196
  ## Source Tree
164
197
 
165
- The source directory is both the Markdown source root and the public passthrough root. GitHub Action usage defaults to `./docs`; CLI usage requires `--source` or `ZEROPRESS_PUBLIC_DIR`.
198
+ The source directory is the folder that Build Pages reads. It is both the Markdown source root and the public passthrough root. GitHub Action usage defaults to `./docs`; CLI usage requires `--source`.
199
+
200
+ Use a dedicated content directory such as `docs/` or `documents/`. Repository root source (`--source ./`) is not supported.
166
201
 
167
202
  ```txt
168
- docs/
169
- index.md
170
- guide.md
171
- assets/
172
- .zeropress/
173
- config.json
203
+ my-site/
204
+ docs/ # source
205
+ index.md
206
+ guide.md
207
+ assets/
208
+ logo.png
209
+ .zeropress/
210
+ config.json
211
+ _site/ # destination, generated
174
212
  ```
175
213
 
176
- Build Pages stages the source tree before calling `@zeropress/build`, so `--source ./` and `--destination ./_site` are supported when you intentionally want to build from the repository root. Generated ZeroPress output wins over staged public files.
214
+ Build Pages stages the source tree before calling [`@zeropress/build`](https://github.com/zeropress-app/zeropress-build). Generated ZeroPress output wins over staged public files.
215
+
216
+ The source directory must not overlap the destination directory, the selected theme directory, or the internal `.zeropress/` working directory.
177
217
 
178
218
  Ignored while staging and Markdown discovery:
179
219
 
@@ -201,7 +241,8 @@ Additional Markdown discovery ignores:
201
241
  - Nested `index.md` maps to a directory route, such as `cli/index.md` -> `/cli/`.
202
242
  - Other Markdown files map to extensionless routes, such as `cli/tool.md` -> `/cli/tool`.
203
243
  - Markdown links to other discovered `.md` files are rewritten to generated public URLs.
204
- - Original Markdown files remain available as public passthrough files.
244
+ - Original Markdown files remain available as public passthrough files by default.
245
+ - Use `--no-copy-markdown-source` or Action input `copy-markdown-source: false` to keep source Markdown out of the generated output. This also hides bundled theme `View this page as Markdown` links.
205
246
 
206
247
  Optional YAML front matter is supported at the top of Markdown files:
207
248
 
@@ -236,6 +277,8 @@ Unknown front matter fields are ignored to make migration from existing Markdown
236
277
 
237
278
  Build Pages reads `<source>/.zeropress/config.json` when present. Missing config falls back to defaults.
238
279
 
280
+ See the public config reference at [zeropress.dev/build-pages-config](https://zeropress.dev/build-pages-config/).
281
+
239
282
  ```json
240
283
  {
241
284
  "$schema": "https://zeropress.dev/schemas/zeropress-build-pages.config.v0.1.schema.json",
@@ -285,12 +328,11 @@ The bundled docs theme shows `Published with ZeroPress.` by default. Set `site.f
285
328
 
286
329
  Schemas:
287
330
 
288
- - `schemas/zeropress-build-pages.config.v0.1.schema.json`
289
- - `schemas/zeropress-build-pages.config.schema.json`
331
+ - [ZeroPress Build Pages Config v0.1](https://zeropress.dev/schemas/zeropress-build-pages.config.v0.1.schema.json)
290
332
 
291
- ## Generated Files
333
+ ## Internal `.zeropress/` Files
292
334
 
293
- Build Pages writes:
335
+ Build Pages writes internal working files to `.zeropress/` in the current working directory. These files are not the final deploy output. The final static site is written to the `destination` directory.
294
336
 
295
337
  ```txt
296
338
  .zeropress/
@@ -300,14 +342,18 @@ Build Pages writes:
300
342
  public-assets/
301
343
  ```
302
344
 
303
- `build-pages-config.json` is the resolved user-facing Build Pages config used for the current run. It combines `.zeropress/config.json`, defaults, and CLI/env overrides where applicable.
345
+ `build-pages-config.json` is the resolved user-facing Build Pages config used for the current run. It combines source config, defaults, and CLI or Action input overrides where applicable.
304
346
 
305
347
  `preview-data.json` is an internal generated build input for the ZeroPress renderer. Most users do not need to edit or understand this file.
306
348
 
307
- ## Development
349
+ `build-report.json` records discovered Markdown counts, skipped Markdown files, front page resolution, source Markdown copy policy, and custom HTML slots.
308
350
 
309
- ```bash
310
- npm install
311
- npm run build:action
312
- npm test
313
- ```
351
+ `public-assets/` is a temporary staged public root used before the final ZeroPress render.
352
+
353
+ ## Destination Output
354
+
355
+ The `destination` directory contains the deployable static site. It includes generated ZeroPress HTML, copied public files, and original Markdown files unless Markdown source copy is disabled or files are excluded by the public passthrough rules.
356
+
357
+ ## Demo
358
+
359
+ - [zeropress.dev](https://github.com/zeropress-app/zeropress.dev) is built with `@zeropress/build-pages`.
package/action.yml CHANGED
@@ -6,7 +6,7 @@ branding:
6
6
  color: blue
7
7
  inputs:
8
8
  source:
9
- description: Source directory containing Markdown files and optional .zeropress/config.json.
9
+ description: Dedicated source directory containing Markdown files and optional .zeropress/config.json. Repository root source is not supported.
10
10
  required: false
11
11
  default: ./docs
12
12
  destination:
@@ -27,11 +27,15 @@ inputs:
27
27
  description: Canonical site URL override.
28
28
  required: false
29
29
  skip-untitled-markdown:
30
- description: Skip Markdown files without an H1 instead of failing.
30
+ description: Skip Markdown files without a page title instead of failing.
31
31
  required: false
32
32
  default: "false"
33
- check-links:
34
- description: Warn about broken internal links after build.
33
+ skip-link-check:
34
+ description: Skip internal link checking after the site is built.
35
+ required: false
36
+ default: "false"
37
+ copy-markdown-source:
38
+ description: Copy original Markdown files to output and expose View this page as Markdown links.
35
39
  required: false
36
40
  default: "true"
37
41
  runs:
package/dist/action.js CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __zeropressCreateRequire } from "node:module";
3
+ const require = __zeropressCreateRequire(import.meta.url);
2
4
  var __create = Object.create;
3
5
  var __defProp = Object.defineProperty;
4
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -62137,18 +62139,26 @@ async function linkExists(siteDir, link2) {
62137
62139
  // src/index.js
62138
62140
  var __dirname = path3.dirname(fileURLToPath(import.meta.url));
62139
62141
  var packageDir = path3.resolve(__dirname, "..");
62140
- var prebuildScript = path3.join(packageDir, "src", "prebuild.js");
62142
+ var prebuildScript = __dirname === path3.join(packageDir, "dist") ? path3.join(__dirname, "prebuild.js") : path3.join(packageDir, "src", "prebuild.js");
62141
62143
  var PREVIEW_DATA_PATH = ".zeropress/preview-data.json";
62142
62144
  var STAGING_DIR = ".zeropress/public-assets";
62143
62145
  var DEFAULT_THEME = "docs";
62144
62146
  async function runBuildPages(options2) {
62145
62147
  const cwd = path3.resolve(options2.cwd || process.cwd());
62148
+ const copyMarkdownSource = options2.copyMarkdownSource !== false;
62146
62149
  const sourceDir = path3.resolve(cwd, options2.source);
62147
62150
  const destinationDir = path3.resolve(cwd, options2.destination);
62148
62151
  const generatedDir = path3.join(cwd, ".zeropress");
62149
62152
  const stagingDir = path3.join(cwd, STAGING_DIR);
62150
62153
  const previewDataPath = path3.join(cwd, PREVIEW_DATA_PATH);
62151
62154
  const themeDir = resolveThemeDir(cwd, options2);
62155
+ assertBuildPagesPathLayout({
62156
+ cwd,
62157
+ sourceDir,
62158
+ destinationDir,
62159
+ themeDir,
62160
+ generatedDir
62161
+ });
62152
62162
  await assertDirectory(sourceDir, "Source directory");
62153
62163
  await fs3.rm(generatedDir, { recursive: true, force: true });
62154
62164
  await fs3.mkdir(generatedDir, { recursive: true });
@@ -62156,7 +62166,8 @@ async function runBuildPages(options2) {
62156
62166
  ...process.env,
62157
62167
  ZEROPRESS_BUILD_PAGES_SOURCE: sourceDir,
62158
62168
  ZEROPRESS_PUBLIC_DIR: sourceDir,
62159
- ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options2.skipUntitledMarkdown))
62169
+ ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options2.skipUntitledMarkdown)),
62170
+ ZEROPRESS_COPY_MARKDOWN_SOURCE: String(copyMarkdownSource)
62160
62171
  };
62161
62172
  if (options2.config) {
62162
62173
  env.ZEROPRESS_BUILD_PAGES_CONFIG = path3.resolve(cwd, options2.config);
@@ -62179,7 +62190,8 @@ async function runBuildPages(options2) {
62179
62190
  await fs3.rm(stagingDir, { recursive: true, force: true });
62180
62191
  await fs3.mkdir(stagingDir, { recursive: true });
62181
62192
  await copyPublicStaging(sourceDir, stagingDir, {
62182
- excludePaths: [destinationDir, themeDir, generatedDir]
62193
+ excludePaths: [destinationDir, themeDir, generatedDir],
62194
+ copyMarkdownSource
62183
62195
  });
62184
62196
  const previousPublicDir = process.env.ZEROPRESS_PUBLIC_DIR;
62185
62197
  process.env.ZEROPRESS_PUBLIC_DIR = stagingDir;
@@ -62195,7 +62207,7 @@ async function runBuildPages(options2) {
62195
62207
  process.env.ZEROPRESS_PUBLIC_DIR = previousPublicDir;
62196
62208
  }
62197
62209
  }
62198
- if (options2.checkLinks) {
62210
+ if (!options2.skipLinkCheck) {
62199
62211
  const result = await checkInternalLinks(destinationDir);
62200
62212
  if (result.brokenLinks.length) {
62201
62213
  console.warn("Warning: broken internal links found:");
@@ -62229,6 +62241,26 @@ async function assertDirectory(dir, label) {
62229
62241
  throw new Error(`${label} is not a directory: ${dir}`);
62230
62242
  }
62231
62243
  }
62244
+ function assertBuildPagesPathLayout({ cwd, sourceDir, destinationDir, themeDir, generatedDir }) {
62245
+ if (samePath(sourceDir, cwd)) {
62246
+ throw new Error(
62247
+ `Source directory must be a dedicated content directory, not the current working directory. Received: ${formatPath(cwd, sourceDir)}`
62248
+ );
62249
+ }
62250
+ assertNoPathOverlap(cwd, "Source directory", sourceDir, "internal .zeropress working directory", generatedDir);
62251
+ assertNoPathOverlap(cwd, "Destination directory", destinationDir, "internal .zeropress working directory", generatedDir);
62252
+ assertNoPathOverlap(cwd, "Theme directory", themeDir, "internal .zeropress working directory", generatedDir);
62253
+ assertNoPathOverlap(cwd, "Source directory", sourceDir, "destination directory", destinationDir);
62254
+ assertNoPathOverlap(cwd, "Source directory", sourceDir, "theme directory", themeDir);
62255
+ }
62256
+ function assertNoPathOverlap(cwd, firstLabel, firstPath, secondLabel, secondPath) {
62257
+ if (!pathsOverlap2(firstPath, secondPath)) {
62258
+ return;
62259
+ }
62260
+ throw new Error(
62261
+ `${firstLabel} must not overlap the ${secondLabel}. ${firstLabel}: ${formatPath(cwd, firstPath)}; ${secondLabel}: ${formatPath(cwd, secondPath)}`
62262
+ );
62263
+ }
62232
62264
  async function copyPublicStaging(sourceDir, targetDir, options2) {
62233
62265
  const entries = await fs3.readdir(sourceDir, { withFileTypes: true });
62234
62266
  for (const entry of entries) {
@@ -62248,6 +62280,9 @@ async function copyPublicStaging(sourceDir, targetDir, options2) {
62248
62280
  if (!entry.isFile()) {
62249
62281
  continue;
62250
62282
  }
62283
+ if (options2.copyMarkdownSource === false && entry.name.toLowerCase().endsWith(".md")) {
62284
+ continue;
62285
+ }
62251
62286
  await fs3.mkdir(path3.dirname(targetPath), { recursive: true });
62252
62287
  await fs3.copyFile(sourcePath, targetPath);
62253
62288
  }
@@ -62265,6 +62300,9 @@ function pathsOverlap2(firstPath, secondPath) {
62265
62300
  const second = path3.resolve(secondPath);
62266
62301
  return first === second || isPathInside2(first, second) || isPathInside2(second, first);
62267
62302
  }
62303
+ function samePath(firstPath, secondPath) {
62304
+ return path3.resolve(firstPath) === path3.resolve(secondPath);
62305
+ }
62268
62306
  function isPathInside2(parentPath, childPath) {
62269
62307
  const relativePath = path3.relative(parentPath, childPath);
62270
62308
  return Boolean(relativePath) && !relativePath.startsWith("..") && !path3.isAbsolute(relativePath);
@@ -62283,7 +62321,8 @@ var options = {
62283
62321
  config: input("config"),
62284
62322
  siteUrl: input("site-url"),
62285
62323
  skipUntitledMarkdown: booleanInput("skip-untitled-markdown", false),
62286
- checkLinks: booleanInput("check-links", true)
62324
+ skipLinkCheck: booleanInput("skip-link-check", false),
62325
+ copyMarkdownSource: falseOnlyInput("copy-markdown-source")
62287
62326
  };
62288
62327
  try {
62289
62328
  await runBuildPages(options);
@@ -62302,3 +62341,6 @@ function booleanInput(name, fallback) {
62302
62341
  }
62303
62342
  return value.toLowerCase() === "true";
62304
62343
  }
62344
+ function falseOnlyInput(name) {
62345
+ return input(name).toLowerCase() !== "false";
62346
+ }