@zeropress/build-pages 0.5.4 → 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
 
@@ -146,23 +191,27 @@ The CLI requires explicit input and output paths. The GitHub Action keeps safe d
146
191
  | `--site-url <url>` | config `site.url` | Canonical URL override |
147
192
  | `--skip-untitled-markdown` | `false` | Skip Markdown without a page title |
148
193
  | `--skip-link-check` | `false` | Skip link checking |
194
+ | `--no-copy-markdown-source` | `false` | Do not copy original Markdown files to output |
149
195
 
150
196
  ## Source Tree
151
197
 
152
- The source directory is both the Markdown source root and the public passthrough root. GitHub Action usage defaults to `./docs`; CLI usage requires `--source`.
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`.
153
199
 
154
- Use a dedicated content directory such as `docs/` or `documents/`. Repository root source (`--source ./`) is not supported, because Build Pages uses `.zeropress/` in the current working directory for internal working files.
200
+ Use a dedicated content directory such as `docs/` or `documents/`. Repository root source (`--source ./`) is not supported.
155
201
 
156
202
  ```txt
157
- docs/
158
- index.md
159
- guide.md
160
- assets/
161
- .zeropress/
162
- 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
163
212
  ```
164
213
 
165
- Build Pages stages the source tree before calling `@zeropress/build`. 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.
166
215
 
167
216
  The source directory must not overlap the destination directory, the selected theme directory, or the internal `.zeropress/` working directory.
168
217
 
@@ -192,7 +241,8 @@ Additional Markdown discovery ignores:
192
241
  - Nested `index.md` maps to a directory route, such as `cli/index.md` -> `/cli/`.
193
242
  - Other Markdown files map to extensionless routes, such as `cli/tool.md` -> `/cli/tool`.
194
243
  - Markdown links to other discovered `.md` files are rewritten to generated public URLs.
195
- - 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.
196
246
 
197
247
  Optional YAML front matter is supported at the top of Markdown files:
198
248
 
@@ -227,6 +277,8 @@ Unknown front matter fields are ignored to make migration from existing Markdown
227
277
 
228
278
  Build Pages reads `<source>/.zeropress/config.json` when present. Missing config falls back to defaults.
229
279
 
280
+ See the public config reference at [zeropress.dev/build-pages-config](https://zeropress.dev/build-pages-config/).
281
+
230
282
  ```json
231
283
  {
232
284
  "$schema": "https://zeropress.dev/schemas/zeropress-build-pages.config.v0.1.schema.json",
@@ -276,8 +328,7 @@ The bundled docs theme shows `Published with ZeroPress.` by default. Set `site.f
276
328
 
277
329
  Schemas:
278
330
 
279
- - `schemas/zeropress-build-pages.config.v0.1.schema.json`
280
- - `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)
281
332
 
282
333
  ## Internal `.zeropress/` Files
283
334
 
@@ -295,18 +346,14 @@ Build Pages writes internal working files to `.zeropress/` in the current workin
295
346
 
296
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.
297
348
 
298
- `build-report.json` records discovered Markdown counts, skipped Markdown files, front page resolution, and custom HTML slots.
349
+ `build-report.json` records discovered Markdown counts, skipped Markdown files, front page resolution, source Markdown copy policy, and custom HTML slots.
299
350
 
300
351
  `public-assets/` is a temporary staged public root used before the final ZeroPress render.
301
352
 
302
353
  ## Destination Output
303
354
 
304
- The `destination` directory contains the deployable static site. It includes generated ZeroPress HTML, copied public files, and original Markdown files unless they are excluded by the public passthrough rules.
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.
305
356
 
306
- ## Development
357
+ ## Demo
307
358
 
308
- ```bash
309
- npm install
310
- npm run build:action
311
- npm test
312
- ```
359
+ - [zeropress.dev](https://github.com/zeropress-app/zeropress.dev) is built with `@zeropress/build-pages`.
package/action.yml CHANGED
@@ -34,6 +34,10 @@ inputs:
34
34
  description: Skip internal link checking after the site is built.
35
35
  required: false
36
36
  default: "false"
37
+ copy-markdown-source:
38
+ description: Copy original Markdown files to output and expose View this page as Markdown links.
39
+ required: false
40
+ default: "true"
37
41
  runs:
38
42
  using: node24
39
43
  main: dist/action.js
package/dist/action.js CHANGED
@@ -62145,6 +62145,7 @@ var STAGING_DIR = ".zeropress/public-assets";
62145
62145
  var DEFAULT_THEME = "docs";
62146
62146
  async function runBuildPages(options2) {
62147
62147
  const cwd = path3.resolve(options2.cwd || process.cwd());
62148
+ const copyMarkdownSource = options2.copyMarkdownSource !== false;
62148
62149
  const sourceDir = path3.resolve(cwd, options2.source);
62149
62150
  const destinationDir = path3.resolve(cwd, options2.destination);
62150
62151
  const generatedDir = path3.join(cwd, ".zeropress");
@@ -62165,7 +62166,8 @@ async function runBuildPages(options2) {
62165
62166
  ...process.env,
62166
62167
  ZEROPRESS_BUILD_PAGES_SOURCE: sourceDir,
62167
62168
  ZEROPRESS_PUBLIC_DIR: sourceDir,
62168
- ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options2.skipUntitledMarkdown))
62169
+ ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options2.skipUntitledMarkdown)),
62170
+ ZEROPRESS_COPY_MARKDOWN_SOURCE: String(copyMarkdownSource)
62169
62171
  };
62170
62172
  if (options2.config) {
62171
62173
  env.ZEROPRESS_BUILD_PAGES_CONFIG = path3.resolve(cwd, options2.config);
@@ -62188,7 +62190,8 @@ async function runBuildPages(options2) {
62188
62190
  await fs3.rm(stagingDir, { recursive: true, force: true });
62189
62191
  await fs3.mkdir(stagingDir, { recursive: true });
62190
62192
  await copyPublicStaging(sourceDir, stagingDir, {
62191
- excludePaths: [destinationDir, themeDir, generatedDir]
62193
+ excludePaths: [destinationDir, themeDir, generatedDir],
62194
+ copyMarkdownSource
62192
62195
  });
62193
62196
  const previousPublicDir = process.env.ZEROPRESS_PUBLIC_DIR;
62194
62197
  process.env.ZEROPRESS_PUBLIC_DIR = stagingDir;
@@ -62277,6 +62280,9 @@ async function copyPublicStaging(sourceDir, targetDir, options2) {
62277
62280
  if (!entry.isFile()) {
62278
62281
  continue;
62279
62282
  }
62283
+ if (options2.copyMarkdownSource === false && entry.name.toLowerCase().endsWith(".md")) {
62284
+ continue;
62285
+ }
62280
62286
  await fs3.mkdir(path3.dirname(targetPath), { recursive: true });
62281
62287
  await fs3.copyFile(sourcePath, targetPath);
62282
62288
  }
@@ -62315,7 +62321,8 @@ var options = {
62315
62321
  config: input("config"),
62316
62322
  siteUrl: input("site-url"),
62317
62323
  skipUntitledMarkdown: booleanInput("skip-untitled-markdown", false),
62318
- skipLinkCheck: booleanInput("skip-link-check", false)
62324
+ skipLinkCheck: booleanInput("skip-link-check", false),
62325
+ copyMarkdownSource: falseOnlyInput("copy-markdown-source")
62319
62326
  };
62320
62327
  try {
62321
62328
  await runBuildPages(options);
@@ -62334,3 +62341,6 @@ function booleanInput(name, fallback) {
62334
62341
  }
62335
62342
  return value.toLowerCase() === "true";
62336
62343
  }
62344
+ function falseOnlyInput(name) {
62345
+ return input(name).toLowerCase() !== "false";
62346
+ }
package/dist/prebuild.js CHANGED
@@ -3531,6 +3531,7 @@ var buildPagesConfigPath = path.join(outDir, "build-pages-config.json");
3531
3531
  var previewDataPath = path.join(outDir, "preview-data.json");
3532
3532
  var buildReportPath = path.join(outDir, "build-report.json");
3533
3533
  var skipUntitledMarkdown = readBooleanEnv("ZEROPRESS_SKIP_UNTITLED_MARKDOWN");
3534
+ var copyMarkdownSource = readBooleanEnv("ZEROPRESS_COPY_MARKDOWN_SOURCE", true);
3534
3535
  var FRONT_PAGE_TYPES = /* @__PURE__ */ new Set(["theme_index", "markdown", "html"]);
3535
3536
  var BUILD_PAGES_CONFIG_SCHEMA_URL = "https://zeropress.dev/schemas/zeropress-build-pages.config.v0.1.schema.json";
3536
3537
  var PREVIEW_DATA_SCHEMA_URL = "https://zeropress.dev/schemas/preview-data.v0.5.schema.json";
@@ -3605,7 +3606,7 @@ async function main() {
3605
3606
  path: route.path,
3606
3607
  meta: {
3607
3608
  ...frontMatter.meta,
3608
- source_markdown_url: buildSourceMarkdownUrl(sourcePath)
3609
+ ...copyMarkdownSource ? { source_markdown_url: buildSourceMarkdownUrl(sourcePath) } : {}
3609
3610
  },
3610
3611
  content: rewriteMarkdownLinks(bodyMarkdown, sourcePath, routeBySourcePath),
3611
3612
  document_type: "markdown",
@@ -4161,6 +4162,7 @@ function buildPrebuildReport({
4161
4162
  preview_data_path: formatSourcePath(previewDataPath),
4162
4163
  report_path: formatSourcePath(buildReportPath),
4163
4164
  skip_untitled_markdown: skipUntitledMarkdown,
4165
+ copy_markdown_source: copyMarkdownSource,
4164
4166
  markdown: {
4165
4167
  discovered: sourceFiles.length,
4166
4168
  generated_pages: pageInputs.length,
@@ -4588,8 +4590,12 @@ function readEnv(name, fallback) {
4588
4590
  function readConfigString(value, fallback) {
4589
4591
  return typeof value === "string" && value.trim() ? value.trim() : fallback;
4590
4592
  }
4591
- function readBooleanEnv(name) {
4592
- return process.env[name]?.trim().toLowerCase() === "true";
4593
+ function readBooleanEnv(name, fallback = false) {
4594
+ const value = process.env[name]?.trim();
4595
+ if (!value) {
4596
+ return fallback;
4597
+ }
4598
+ return value.toLowerCase() === "true";
4593
4599
  }
4594
4600
  function resolveEnvPath(names, fallback) {
4595
4601
  const rawValue = names.map((name) => process.env[name]?.trim()).find(Boolean) || fallback;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeropress/build-pages",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "ZeroPress Markdown build action and CLI for static hosting",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/action.js CHANGED
@@ -9,6 +9,7 @@ const options = {
9
9
  siteUrl: input('site-url'),
10
10
  skipUntitledMarkdown: booleanInput('skip-untitled-markdown', false),
11
11
  skipLinkCheck: booleanInput('skip-link-check', false),
12
+ copyMarkdownSource: falseOnlyInput('copy-markdown-source'),
12
13
  };
13
14
 
14
15
  try {
@@ -30,3 +31,7 @@ function booleanInput(name, fallback) {
30
31
  }
31
32
  return value.toLowerCase() === 'true';
32
33
  }
34
+
35
+ function falseOnlyInput(name) {
36
+ return input(name).toLowerCase() !== 'false';
37
+ }
package/src/index.js CHANGED
@@ -37,6 +37,7 @@ export async function runCli(argv = process.argv.slice(2)) {
37
37
 
38
38
  export async function runBuildPages(options) {
39
39
  const cwd = path.resolve(options.cwd || process.cwd());
40
+ const copyMarkdownSource = options.copyMarkdownSource !== false;
40
41
  const sourceDir = path.resolve(cwd, options.source);
41
42
  const destinationDir = path.resolve(cwd, options.destination);
42
43
  const generatedDir = path.join(cwd, '.zeropress');
@@ -60,6 +61,7 @@ export async function runBuildPages(options) {
60
61
  ZEROPRESS_BUILD_PAGES_SOURCE: sourceDir,
61
62
  ZEROPRESS_PUBLIC_DIR: sourceDir,
62
63
  ZEROPRESS_SKIP_UNTITLED_MARKDOWN: String(Boolean(options.skipUntitledMarkdown)),
64
+ ZEROPRESS_COPY_MARKDOWN_SOURCE: String(copyMarkdownSource),
63
65
  };
64
66
  if (options.config) {
65
67
  env.ZEROPRESS_BUILD_PAGES_CONFIG = path.resolve(cwd, options.config);
@@ -85,6 +87,7 @@ export async function runBuildPages(options) {
85
87
  await fs.mkdir(stagingDir, { recursive: true });
86
88
  await copyPublicStaging(sourceDir, stagingDir, {
87
89
  excludePaths: [destinationDir, themeDir, generatedDir],
90
+ copyMarkdownSource,
88
91
  });
89
92
 
90
93
  const previousPublicDir = process.env.ZEROPRESS_PUBLIC_DIR;
@@ -127,6 +130,10 @@ export function parseArgs(argv) {
127
130
  flags.skipLinkCheck = true;
128
131
  continue;
129
132
  }
133
+ if (arg === '--no-copy-markdown-source') {
134
+ flags.copyMarkdownSource = false;
135
+ continue;
136
+ }
130
137
 
131
138
  const valueOptions = new Set([
132
139
  '--source',
@@ -167,6 +174,7 @@ export function parseArgs(argv) {
167
174
  siteUrl: flags['site-url'] || '',
168
175
  skipUntitledMarkdown: flags.skipUntitledMarkdown === true,
169
176
  skipLinkCheck: flags.skipLinkCheck === true,
177
+ copyMarkdownSource: flags.copyMarkdownSource !== false,
170
178
  };
171
179
  }
172
180
 
@@ -185,6 +193,7 @@ Options:
185
193
  --site-url <url> Canonical site URL override
186
194
  --skip-untitled-markdown Skip Markdown files without a page title
187
195
  --skip-link-check Skip internal link checking
196
+ --no-copy-markdown-source Do not copy original Markdown files to output
188
197
  --help, -h Show help
189
198
  --version, -v Show version`);
190
199
  }
@@ -264,6 +273,10 @@ async function copyPublicStaging(sourceDir, targetDir, options) {
264
273
  continue;
265
274
  }
266
275
 
276
+ if (options.copyMarkdownSource === false && entry.name.toLowerCase().endsWith('.md')) {
277
+ continue;
278
+ }
279
+
267
280
  await fs.mkdir(path.dirname(targetPath), { recursive: true });
268
281
  await fs.copyFile(sourcePath, targetPath);
269
282
  }
package/src/prebuild.js CHANGED
@@ -13,6 +13,7 @@ const buildPagesConfigPath = path.join(outDir, 'build-pages-config.json');
13
13
  const previewDataPath = path.join(outDir, 'preview-data.json');
14
14
  const buildReportPath = path.join(outDir, 'build-report.json');
15
15
  const skipUntitledMarkdown = readBooleanEnv('ZEROPRESS_SKIP_UNTITLED_MARKDOWN');
16
+ const copyMarkdownSource = readBooleanEnv('ZEROPRESS_COPY_MARKDOWN_SOURCE', true);
16
17
  const FRONT_PAGE_TYPES = new Set(['theme_index', 'markdown', 'html']);
17
18
  const BUILD_PAGES_CONFIG_SCHEMA_URL = 'https://zeropress.dev/schemas/zeropress-build-pages.config.v0.1.schema.json';
18
19
  const PREVIEW_DATA_SCHEMA_URL = 'https://zeropress.dev/schemas/preview-data.v0.5.schema.json';
@@ -96,7 +97,7 @@ async function main() {
96
97
  path: route.path,
97
98
  meta: {
98
99
  ...frontMatter.meta,
99
- source_markdown_url: buildSourceMarkdownUrl(sourcePath),
100
+ ...(copyMarkdownSource ? { source_markdown_url: buildSourceMarkdownUrl(sourcePath) } : {}),
100
101
  },
101
102
  content: rewriteMarkdownLinks(bodyMarkdown, sourcePath, routeBySourcePath),
102
103
  document_type: 'markdown',
@@ -733,6 +734,7 @@ function buildPrebuildReport({
733
734
  preview_data_path: formatSourcePath(previewDataPath),
734
735
  report_path: formatSourcePath(buildReportPath),
735
736
  skip_untitled_markdown: skipUntitledMarkdown,
737
+ copy_markdown_source: copyMarkdownSource,
736
738
  markdown: {
737
739
  discovered: sourceFiles.length,
738
740
  generated_pages: pageInputs.length,
@@ -1305,8 +1307,12 @@ function readConfigInteger(value, fallback) {
1305
1307
  return Number.isInteger(value) && value > 0 ? value : fallback;
1306
1308
  }
1307
1309
 
1308
- function readBooleanEnv(name) {
1309
- return process.env[name]?.trim().toLowerCase() === 'true';
1310
+ function readBooleanEnv(name, fallback = false) {
1311
+ const value = process.env[name]?.trim();
1312
+ if (!value) {
1313
+ return fallback;
1314
+ }
1315
+ return value.toLowerCase() === 'true';
1310
1316
  }
1311
1317
 
1312
1318
  function resolveEnvPath(names, fallback) {