native-packages 0.6.0 → 0.7.0

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.
@@ -0,0 +1,172 @@
1
+ ---
2
+ title: Troubleshooting
3
+ description: Resolve missing tools and inputs, architecture errors, recipe issues, and publication failures.
4
+ nav_order: 4
5
+ ---
6
+
7
+ # Troubleshooting
8
+
9
+ Start with these commands from your application directory:
10
+
11
+ ```sh
12
+ native-packages validate
13
+ native-packages doctor
14
+ native-packages build --version 1.2.3 --dry-run
15
+ ```
16
+
17
+ They check configuration, packaging tools, and the planned inputs respectively.
18
+ For a configuration with several native hosts, select the target you are
19
+ working on with `doctor --target ID` and `build --target ID --dry-run`.
20
+
21
+ ## The configuration needs another tool version
22
+
23
+ Install and select the version named in the error:
24
+
25
+ ```sh
26
+ gem install native-packages --version 0.7.0
27
+ native-packages _0.7.0_ doctor
28
+ ```
29
+
30
+ `tool.version` is an exact match. In CI, use the matching released reusable
31
+ workflow. To upgrade, update the configuration and workflow together.
32
+
33
+ ## nFPM or an inspection tool is missing
34
+
35
+ Linux and MSIX packaging require nFPM 2.47.0. Linux binary inspection needs
36
+ `readelf`; archive extraction needs `bsdtar`. Install these using the
37
+ [setup instructions](../_guides/getting-started.md#1-install-the-tools).
38
+
39
+ DMG and Inno targets do not require an nFPM executable. If you only intend to
40
+ build a native target, select it explicitly so `doctor` does not check Linux
41
+ targets from the same configuration.
42
+
43
+ ## An input does not exist
44
+
45
+ Check the path relative to the configuration file, not your shell's current
46
+ directory. Make sure your build script produced the expected file and that
47
+ any `@VERSION@` value matches the version you requested.
48
+
49
+ For a single executable use `input.kind: file`; for a prepared directory use
50
+ `directory`. The default is `archive`.
51
+
52
+ ## A package content file is missing
53
+
54
+ Check the input's internal layout. Archives retain top-level folders. If an
55
+ archive contains `hello-1.2.3/hello`, the source is
56
+ `@PAYLOAD@/hello-1.2.3/hello`. For a file input, the payload contains the
57
+ input file's basename.
58
+
59
+ A target-specific `nfpm.contents` list replaces the shared list entirely.
60
+ Include all the files needed by that target.
61
+
62
+ ## Wrong architecture or C library
63
+
64
+ Rebuild the application for the platform and architecture declared by the
65
+ target, or correct the target to match your intended build. An ARM64 binary
66
+ cannot satisfy `arch: amd64`.
67
+
68
+ If the tool reports a static target containing dynamic binaries, use the
69
+ appropriate `libc: glibc` or `musl`, or produce a truly static build. Adding a
70
+ new package format does not change the binary's runtime requirements.
71
+
72
+ ## A shared library has no package mapping
73
+
74
+ For DEB/RPM, add the library's distribution package names under
75
+ [`libraries`](configuration.md#libraries). For other formats, declare runtime
76
+ dependencies explicitly. If the library is bundled, make sure it is included
77
+ in `contents`. Confirm dependency names on your supported distributions.
78
+
79
+ ## The output directory already exists
80
+
81
+ Choose a new output path:
82
+
83
+ ```sh
84
+ native-packages build --version 1.2.3 --output dist/rebuild-1.2.3
85
+ ```
86
+
87
+ Builds and aggregation preserve existing outputs. Keep earlier builds until
88
+ you have reviewed the replacement.
89
+
90
+ ## There is no exact release tag at HEAD
91
+
92
+ Pass the app version for a local build:
93
+
94
+ ```sh
95
+ native-packages build --version 1.2.3
96
+ ```
97
+
98
+ Version inference requires an exact supported release tag on the current
99
+ commit. Native installer targets always consume local prepared directories,
100
+ even when those files originated in a release job.
101
+
102
+ ## A release checksum is missing or incorrect
103
+
104
+ The input filename must appear in the release's `checksums.txt` (or configured
105
+ `release.checksums`). Generate the hash from the exact archive you upload.
106
+ Check that the version and `release_asset` name agree with the release.
107
+
108
+ Do not bypass checksums for binary inputs. `checksummed: false` is available
109
+ for additional source assets intentionally omitted from the release checksum
110
+ list. See [Publishing a release](../_guides/publishing.md).
111
+
112
+ ## A recipe value is unresolved
113
+
114
+ Check the token spelling and asset key. Asset names are uppercase:
115
+ `assets.MACOS` supplies `@MACOS_FILE@`, `@MACOS_URL@`, and `@MACOS_SHA256@`.
116
+ Target-only values such as `@ARCH@` are not available in global recipes.
117
+
118
+ During a deferred build, recipe asset hashes are not known yet. If a target
119
+ itself needs one of those hashes, use an ordinary build with the asset
120
+ available. See [replacement values](configuration.md#replacement-values).
121
+
122
+ ## AUR tools are requested on macOS or Windows
123
+
124
+ Use `build --defer-recipes` and `doctor --defer-recipes` in native jobs, then
125
+ finalize recipes on Linux after collecting all packages. See
126
+ [Building across platforms](../_guides/multi-platform.md).
127
+
128
+ ## Aggregation says builds disagree
129
+
130
+ Use the same configuration, app version, timestamp, and checkout across jobs.
131
+ For deferred builds, Git-derived recipe metadata must also agree; use the same
132
+ Git history depth. Include all configured targets and formats exactly once.
133
+
134
+ Use `--finalize-recipes` for deferred inputs. Do not mix ordinary and deferred
135
+ build directories. Preserve hidden recipe files while moving CI artifacts.
136
+
137
+ ## Publication rejects the build
138
+
139
+ Common causes are a changed configuration, missing formats, or files modified
140
+ after their hashes were recorded. Signing belongs inside the build's output
141
+ hook; rebuild if signing happened afterward.
142
+
143
+ Use the original configuration and complete output directory. For separate
144
+ release jobs, `publish --target ID` requires exactly those complete targets.
145
+ It does not allow publishing one format from a target that declares several.
146
+
147
+ A deferred result needs finalization. A prerelease upload also needs an
148
+ existing GitHub release marked as a prerelease.
149
+
150
+ ## A downstream update cannot be staged or pushed
151
+
152
+ Read `native-packages diff TARGET` and inspect the managed checkout named in
153
+ the error under `.cache/packaging/repos/`. The tool rejects unrelated dirty
154
+ files, an existing unpublished update, unexpected remote changes, and downgrades.
155
+ Resolve the reported state before retrying. PR/MR publication also requires
156
+ a reviewed `--body-file` and valid fork credentials.
157
+
158
+ ## Apple signing fails or is skipped
159
+
160
+ All six [Apple environment variables](../_guides/apple-notarization.md#1-set-up-your-apple-credentials)
161
+ are needed. None means an unsigned build; an incomplete set fails explicitly.
162
+ Check the exact identity, export password, Team ID, and app-specific password.
163
+
164
+ A native script must package `@PAYLOAD@` and preserve its signatures. A failure
165
+ from Apple's service prevents a completed signed build. Use the submission
166
+ information in the error to investigate Apple's result before retrying.
167
+
168
+ ## Get help
169
+
170
+ If the error persists, [open an issue](https://github.com/crmne/native-packages/issues)
171
+ with the command, tool version, host platform, relevant configuration, and
172
+ error message. Remove credentials and private download URLs before sharing.
@@ -1,90 +1,5 @@
1
1
  # Apple signing and notarization
2
2
 
3
- Since native-packages 0.5.0, a native macOS DMG build automatically signs and
4
- notarizes when all six environment variables below are present. No variables
5
- preserves existing local/unsigned behavior. Any incomplete set fails with the
6
- missing variable names before packaging. Linux and Windows targets ignore these
7
- Apple variables. `validate` and `build --dry-run` remain offline.
3
+ This guide is now part of the documentation site:
8
4
 
9
- | Environment variable | Value |
10
- | --- | --- |
11
- | `APPLE_CERTIFICATE_P12` | Base64-encoded Developer ID Application certificate and private key, exported as PKCS#12 |
12
- | `APPLE_CERTIFICATE_PASSWORD` | Password protecting that export |
13
- | `APPLE_SIGNING_IDENTITY` | Exact `Developer ID Application: Name (TEAMID)` identity |
14
- | `APPLE_ID` | Apple Account email |
15
- | `APPLE_TEAM_ID` | Developer Program Team ID |
16
- | `APPLE_APP_PASSWORD` | Apple Account app-specific password |
17
-
18
- Store these in CI secrets and expose them as environment variables only in the
19
- trusted macOS release job. The gem does not fetch secrets from a password manager
20
- or GitHub. A free Apple account cannot replace Developer Program membership and
21
- a valid Developer ID Application certificate.
22
-
23
- ## Native DMG builds
24
-
25
- Build the application's complete `.app` and prepare its configured native input
26
- first, then run the normal command on macOS:
27
-
28
- ```sh
29
- native-packages --config native-packages.macos.yaml build \
30
- --version 1.2.3 --target macos-universal --output dist/macos-packages
31
- ```
32
-
33
- The gem imports the certificate and notary credentials into a fresh, temporary
34
- keychain. Since 0.5.1, it adds that keychain to the user's search list when needed
35
- on a clean runner, retaining existing entries and leaving the default keychain
36
- unchanged. Signing calls under the same OS user share a lock, so parallel native
37
- packaging hooks wait for the active signing call instead of racing search-list
38
- updates. It deletes only its own keychain and search-list entry after success or
39
- failure, preserving keychains added by other processes. Credential values are excluded from
40
- manifests and redacted from tool errors.
41
-
42
- The input is copied and checked before signing. All Mach-O code and nested
43
- frameworks/app bundles in the owned copy are signed from the inside out with a
44
- secure timestamp and hardened runtime. Existing entitlements and requirements
45
- are preserved; the gem does not invent exceptions such as disabling library
46
- validation. The application remains responsible for any required entitlements.
47
-
48
- Signing finishes **before `native.command`**. Its recipe must copy `@PAYLOAD@`
49
- unchanged, create the configured DMG, and avoid replacing signatures with ad-hoc
50
- ones. The original application input remains unchanged. `after_package` still
51
- runs, then the gem signs the DMG, submits it with `notarytool`, waits for Apple's
52
- `Accepted` result, staples and validates the ticket, and verifies the image.
53
- Only then are package hashes and the build manifest written. The manifest's
54
- package validation records Apple acceptance, submission ID and stapling.
55
-
56
- Remove redundant Apple signing and notarization from application hooks when
57
- adopting this flow. Existing Inno/MSIX signing hooks remain independent.
58
- Submission waits up to 30 minutes; failure or timeout prevents publication of a
59
- completed build. Apple may continue processing a timed-out submission.
60
-
61
- ## Portable macOS archives
62
-
63
- A standalone executable cannot carry a stapled ticket, and Apple does not accept
64
- `.tar.gz` as a submission. Prepare the entire portable tree, including binaries,
65
- dylibs, models and notices, then use:
66
-
67
- ```sh
68
- native-packages notarize-macos portable-input \
69
- --output signed/Example-1.2.3-macos-arm64
70
- tar czf Example-1.2.3-macos-arm64.tar.gz \
71
- -C signed Example-1.2.3-macos-arm64
72
- ```
73
-
74
- The destination must be new and outside the input directory. This command needs
75
- no application configuration. With credentials, it signs only its copy, submits
76
- that exact code through a temporary ZIP, waits for acceptance, and staples and
77
- validates any `.app` bundles. It then publishes the signed directory atomically.
78
- Archive only that returned tree; do not modify its signed contents. Without
79
- credentials it copies the input unchanged and explicitly reports that signing
80
- and notarization were skipped.
81
-
82
- Standalone binaries rely on Gatekeeper's online ticket lookup. An accepted
83
- portable submission does not claim offline stapling support for raw executables.
84
- Notarization also does not replace app startup, model/GPU, entitlement, OS-version
85
- or installation testing. Test a fresh downloaded package with Gatekeeper before
86
- announcing the first notarized release.
87
-
88
- Apple references: [Developer ID certificates](https://developer.apple.com/help/account/certificates/create-developer-id-certificates/),
89
- [signing distribution code](https://developer.apple.com/documentation/xcode/creating-distribution-signed-code-for-the-mac/),
90
- [notarization](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution).
5
+ [Apple signing and notarization](_guides/apple-notarization.md).
@@ -0,0 +1,27 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" role="img" aria-labelledby="title desc">
2
+ <title id="title">native-packages logo</title>
3
+ <desc id="desc">An indigo package with a pale blue sealing strip and a terminal prompt on its side.</desc>
4
+ <defs>
5
+ <linearGradient id="top" x1="44" y1="44" x2="212" y2="132" gradientUnits="userSpaceOnUse">
6
+ <stop stop-color="#a5b4fc"/>
7
+ <stop offset="1" stop-color="#818cf8"/>
8
+ </linearGradient>
9
+ <linearGradient id="left" x1="44" y1="88" x2="128" y2="220" gradientUnits="userSpaceOnUse">
10
+ <stop stop-color="#6366f1"/>
11
+ <stop offset="1" stop-color="#4f46e5"/>
12
+ </linearGradient>
13
+ <linearGradient id="right" x1="128" y1="132" x2="212" y2="174" gradientUnits="userSpaceOnUse">
14
+ <stop stop-color="#4338ca"/>
15
+ <stop offset="1" stop-color="#3730a3"/>
16
+ </linearGradient>
17
+ </defs>
18
+ <path d="M128 36 220 84 128 132 36 84Z" fill="url(#top)"/>
19
+ <path d="M36 84 128 132V228L36 180Z" fill="url(#left)"/>
20
+ <path d="m128 132 92-48v96l-92 48Z" fill="url(#right)"/>
21
+ <path d="m80 61 92 48 20-10-92-48Z" fill="#e0e7ff"/>
22
+ <path d="m172 109 20-10v43l-10-1-10 12Z" fill="#a5b4fc"/>
23
+ <g fill="none" stroke="#eef2ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="6">
24
+ <path d="m59 122 14 18-14 4"/>
25
+ <path d="m86 156 17 9"/>
26
+ </g>
27
+ </svg>
@@ -1,162 +1,5 @@
1
1
  # Configuration reference
2
2
 
3
- `native-packages.yaml` (or `.yml`) is discovered in the working directory. `--config FILE` selects a different file; relative paths resolve from that file's directory. The schema uses data only: no Ruby evaluation or general template expressions.
3
+ This guide is now part of the documentation site:
4
4
 
5
- | Field | Purpose |
6
- | --- | --- |
7
- | `schema` | Configuration schema version; currently `1`. |
8
- | `tool.version` | Exact native-packages gem version. A mismatch reports the install/version-selection command. |
9
- | `tool.nfpm` | Supported nFPM version; currently `2.47.0`. |
10
- | `nfpm` | Native nFPM configuration mapping, or a relative YAML filename. Name, contents, dependencies, hooks and signing use nFPM's schema. |
11
- | `targets` | Named platform/architecture/input/format combinations. May be empty for recipe-only projects. |
12
- | `release` | Optional GitHub `repository` and checksum filename (`checksums.txt` by default). |
13
- | `assets` | Additional recipe assets, keyed by uppercase identifiers. |
14
- | `templates` | Output recipe paths mapped to input template paths. |
15
- | `repositories` | The existing downstream registry entries, without the old `version`/`repositories` wrapper. Defaults to empty. |
16
- | `libraries` | Additional shared-library-to-package dependency mappings, keyed by SONAME then format. |
17
- | `revisions` | Per-version/per-template package revisions, preserving the v0.1 format. |
18
- | `version_file`, `version_section` | Existing Cargo manifest version checks used by `check-version`. |
19
-
20
- ## Targets
21
-
22
- Version 0.3 additionally accepts macOS `dmg` and Windows `inno` targets with an
23
- application-owned `native.command` and `native.output`. These consume local
24
- prepared directories on their native host, with no nFPM executable required.
25
- See [native recipes](native-recipes.md) for the complete contract and examples.
26
- The nFPM targets below retain their existing behavior.
27
-
28
- A target declares `platform` (`linux` or `windows`), `arch` (nFPM/Go architecture name), `formats`, and `input`. `kind` defaults to `binary`; `data` permits packages without executables, and `source` is required for a separate SRPM target. Linux binaries declare `libc` as `glibc`, `musl` or `static`. IPK also requires an `abi` label identifying the device/distribution baseline.
29
-
30
- A target's optional `nfpm` mapping overrides the shared definition. Maps merge recursively; lists replace in full. Package name, version, platform and architecture must not conflict with their canonical declarations. Format-specific architecture overrides belong in the corresponding nFPM section. Distinct target inputs must be supplied for incompatible ABIs or platforms.
31
-
32
- `input.local` is a path. `input.release_asset` is a filename; `input.url` can override its GitHub release URL. `input.kind` is `archive` (default), `directory` or `file`. Binary release inputs always require a matching release checksum. Archive extraction and Linux inspection require `bsdtar` and `readelf`, respectively.
33
-
34
- `before_build` is an argument array, for example:
35
-
36
- ```yaml
37
- before_build: [./scripts/build-linux.sh, '@ARCH@']
38
- ```
39
-
40
- It runs once per selected target in the configuration directory, before copying local inputs. `NATIVE_PACKAGES_TARGET` and `NATIVE_PACKAGES_VERSION` are also set. It is skipped in release mode and never executed by `validate`, `doctor` or a dry run. A shell script remains responsible for complex build operations.
41
-
42
- `after_package` is an optional argument array invoked once per generated package, before output hashes are recorded. For native DMG targets, automatic [Apple notarization](apple-notarization.md) runs after this hook; input signing completes before the native recipe. It additionally receives `@PACKAGE@` and `@FORMAT@`. Use it for existing native signing tools, for example a Windows SDK SignTool script. It runs in local and release mode and must preserve the output filename and file set. The MSIX acceptance test uses SignTool because Windows rejected the signature produced by nFPM 2.47.0's built-in signer in that test.
43
-
44
- ## Tokens and additional assets
45
-
46
- Strings can contain `@NAME@`, `@VERSION@`, `@TAG@`, `@DATE@`, `@SOURCE_DATE_EPOCH@`, `@ROOT@`, `@UPSTREAM@` and `@GIT_VERSION@`. Target definitions additionally receive `@ARCH@`, `@PLATFORM@`, `@TARGET_ID@`, `@TARGET@` and `@PAYLOAD@`. `TARGET` is the explicit `compiler_target` or, if omitted, the target ID. `PAYLOAD` is the extracted/copied input directory. Recipe templates also receive `@PKGREL@`.
47
-
48
- Additional `assets` retain the existing `file`, optional `url`, and `checksummed` fields. Local builds require `local` paths for these assets. Release builds download and hash them, checking the published checksum unless `checksummed: false` is explicitly set for a source asset. Each contributes `@KEY_FILE@`, `@KEY_URL@` and `@KEY_SHA256@` to recipe rendering. Unresolved tokens fail validation/build.
49
-
50
- Omitting `--version` requires an exact supported release tag at HEAD. `--release` supplies the version and conflicts with a different `--version`. Versions default to stable `vMAJOR.MINOR.PATCH`. Setting `release.prereleases: true` additionally permits `-alpha.N`, `-beta.N` and `-rc.N` for DEB/RPM/DMG/Inno builds without downstream recipes; preview upload requires an existing GitHub prerelease. Native directory recipes use local `--version` mode. Build timestamps use `SOURCE_DATE_EPOCH`, otherwise the relevant Git commit timestamp, otherwise the current time for projects without Git metadata. Supply `SOURCE_DATE_EPOCH` for repeatable builds outside Git.
51
-
52
- ## Output and publication
53
-
54
- `build` writes a fresh `dist/packages/<version>` directory, or the explicit `--output` path. It refuses an existing output. Each target/format gets its own directory and nFPM chooses the native filename. `build.json` records the configuration digest, targets, input/output hashes and validation performed. It does not claim the application was installed or tested on each distro.
55
-
56
- `publish --from DIRECTORY --to github,aur` verifies the entire configured target set and file hashes before publishing. `github` means release assets; other names select a configured downstream destination or group. GitHub asset filenames must be unique across variants. Upstream `checksums.txt` is preserved and package upload checksums use `packaging-checksums.txt`.
57
-
58
- For builds split across CI jobs:
59
-
60
- ```sh
61
- native-packages build --version 1.2.3 --target linux-amd64 --output dist/linux
62
- native-packages build --version 1.2.3 --target windows-amd64 --output dist/windows
63
- native-packages aggregate dist/linux dist/windows --output dist/complete
64
- native-packages publish --from dist/complete --to github
65
- ```
66
-
67
- Each build must use the same configuration, release version and timestamp. Aggregate rejects duplicate target/format outputs, conflicting recipe files and incomplete sets. Publishing recipes can still use the existing reviewed sequence: `stage TARGET DIRECTORY/recipes`, `diff TARGET`, then `publish TARGET --body-file FILE` where required by a submission destination.
68
-
69
-
70
- ## Deferred recipe generation
71
-
72
- Since 0.4.0, use this opt-in sequence when downstream recipes depend
73
- on packages built in separate jobs. The existing build and aggregate commands
74
- keep generating and checking recipes as before when the new flags are absent.
75
- There are no new configuration keys.
76
-
77
- ```sh
78
- # Run each target on its required host, with the same checkout and epoch.
79
- native-packages doctor --target linux-amd64 --defer-recipes
80
- native-packages build --version 1.2.3 --target linux-amd64 --defer-recipes --output dist/linux
81
- native-packages build --version 1.2.3 --target macos-universal --defer-recipes --output dist/macos
82
- native-packages build --version 1.2.3 --target windows-amd64 --defer-recipes --output dist/windows
83
-
84
- # Download those build directories and remaining recipe assets onto Linux.
85
- native-packages aggregate dist/linux dist/macos dist/windows --finalize-recipes --output dist/complete
86
- # Run the application's package installation/upgrade/removal checks here.
87
- native-packages publish --from dist/complete --to github,aur,homebrew
88
- ```
89
-
90
- A deferred build still validates configuration, selected inputs, architecture,
91
- container contents and signing hooks. It does not acquire the global `assets`
92
- or generate `templates`. `doctor --defer-recipes` likewise omits recipe tooling;
93
- the selected package formats still need their own tools. Asset filenames and
94
- URLs are available as tokens, but unknown `@KEY_SHA256@` values cannot be used
95
- by a target's input, package definition or hooks. Such a target must use the
96
- normal build path with its assets already available. Release-mode target inputs
97
- still require their published checksums, even with `--defer-recipes`.
98
-
99
- The finalizer first verifies every input manifest and the complete target set.
100
- All inputs must defer recipes and agree on configuration, version, timestamp,
101
- tool and recipe metadata, including Git version. Use the same Git history depth
102
- and `SOURCE_DATE_EPOCH` on every host. Mixing ordinary and deferred builds fails.
103
- Neither a partial target set nor a deferred build can be published. An ordinary
104
- aggregate rejects deferred inputs unless `--finalize-recipes` is supplied.
105
-
106
- For each global asset, finalization first looks for a verified package whose
107
- release filename exactly matches the asset's rendered `file`. For example,
108
- `assets.MACOS.file: app-v@VERSION@-macos-universal.dmg` resolves to a native target
109
- with that output filename. Its hash includes the completed signing/notarization
110
- hook. A stale `local` file cannot override that package. Duplicate package
111
- filenames are rejected. The manifest records this asset by package filename
112
- and digest, without a temporary staging path.
113
-
114
- Other assets, such as portable or source archives, must be staged at their
115
- configured `local` paths on the finalization host. Finalization reads local
116
- inputs and does not download recipe assets from a release. This also applies
117
- when the deferred target builds used `--release`. Recipe tools run only here:
118
- AUR templates require makepkg or working Docker, and recipe archives require
119
- tar and xz. The finalizer renders and validates recipes, writes the recipe
120
- archive and complete manifest, and atomically creates a fresh output directory.
121
- Failure leaves the original target directories intact and creates no completed
122
- output. Existing destinations are never overwritten.
123
-
124
- Deferral does not enable stable downstream recipes in a prerelease configuration.
125
- The existing preview-format and stable-recipe restrictions still apply. Use a
126
- preview configuration without downstream templates when building previews.
127
-
128
- ## One configuration across native hosts
129
-
130
- Keep Linux, macOS and Windows targets in the same `native-packages.yaml`.
131
- Build native inputs on their native host. Use `--defer-recipes` there when
132
- stable distribution recipes need assets that have not yet been published:
133
-
134
- ```sh
135
- native-packages build --version 1.2.3 --target macos-universal --defer-recipes
136
- ```
137
-
138
- The application's release job may collect that native output directly. If it
139
- uses the shared Linux packaging workflow afterward, set its `targets` input
140
- to the complete Linux target IDs, for example `linux-amd64,linux-arm64`.
141
- The workflow passes that exact selection to both build and publication.
142
- An empty input retains the original all-target behavior. Native targets still
143
- require their native host; selecting a Mac target does not turn an Ubuntu job
144
- into a Mac runner.
145
-
146
- The corresponding CLI publication is explicit:
147
-
148
- ```sh
149
- native-packages build --release v1.2.3 --target linux-amd64 --target linux-arm64
150
- native-packages publish --from dist/packages/1.2.3 --to github \
151
- --target linux-amd64 --target linux-arm64
152
- ```
153
-
154
- Every format for every selected target must be present, and no extra targets
155
- may be in that build. Unknown IDs, missing formats, altered files, unfinished
156
- recipes and configuration mismatches still fail before publication. Omitting
157
- `--target` requires all targets from the configuration. This does not authorize
158
- publishing an arbitrary partial build.
159
-
160
- With `release.prereleases: true`, `--defer-recipes` also permits a native
161
- prerelease to share its config with stable AUR/Homebrew templates. Those
162
- recipes remain deferred and cannot be finalized or published for a prerelease.
5
+ [Configuration reference](_reference/configuration.md).
data/docs/index.md ADDED
@@ -0,0 +1,41 @@
1
+ ---
2
+ layout: home
3
+ title: native-packages
4
+ description: Turn your built application into Linux packages, macOS disk images, and Windows installers. Publish releases from one configuration.
5
+ permalink: /
6
+ hero:
7
+ name: native-packages
8
+ text: Turn your app into installable packages
9
+ tagline: One configuration. Linux, macOS, and Windows. Build packages and publish them with every release.
10
+ actions:
11
+ - theme: brand
12
+ text: Get started
13
+ link: /getting-started/
14
+ - theme: alt
15
+ text: GitHub
16
+ link: https://github.com/crmne/native-packages
17
+ image:
18
+ src: /assets/images/logo.svg
19
+ alt: native-packages logo
20
+ width: 320
21
+ height: 320
22
+ features:
23
+ - icon: 📦
24
+ title: One configuration
25
+ details: Describe your app's files, package metadata, and build targets in a single YAML file.
26
+ - icon: 🐧
27
+ title: Linux packages
28
+ details: Create DEB, RPM, Arch, Alpine, and IPK packages from your compatible Linux builds.
29
+ - icon: 🖥️
30
+ title: Native installers
31
+ details: Connect your macOS DMG and Windows Inno Setup scripts, or package Windows apps as MSIX.
32
+ - icon: 🚀
33
+ title: Release automation
34
+ details: Build from local files or release assets. Add packaging to GitHub Actions and upload the finished packages.
35
+ - icon: 🍺
36
+ title: AUR and Homebrew
37
+ details: Fill in versions, download URLs, and checksums in your recipes, then review and publish the updates.
38
+ - icon: 🔎
39
+ title: Verified builds
40
+ details: Check binary architecture and library requirements. Record file hashes and verify them before publishing.
41
+ ---
@@ -1,136 +1,5 @@
1
- # Native DMG and Inno recipes
1
+ # macOS and Windows installers
2
2
 
3
- The shared build command can coordinate existing macOS and Windows packaging
4
- scripts. These are native command adapters, separate from nFPM. They do not
5
- generate an installer recipe or compile an app. Since 0.5.0, complete Apple
6
- credentials automatically enable Developer ID signing and notarization for DMG
7
- targets. The application supplies its identity, bundle contents and entitlements.
8
- See [Apple notarization](apple-notarization.md).
3
+ This guide is now part of the documentation site:
9
4
 
10
- ```yaml
11
- schema: 1
12
- tool:
13
- version: '0.6.0'
14
- nfpm: '2.47.0'
15
- nfpm:
16
- name: example-app
17
- maintainer: Example <example@example.org>
18
- description: Example application
19
- license: MIT
20
- release:
21
- repository: example/example-app
22
- prereleases: true
23
- targets:
24
- macos-arm64:
25
- platform: macos
26
- arch: arm64
27
- formats: [dmg]
28
- input:
29
- kind: directory
30
- local: Example.app
31
- native:
32
- command: [ruby, packaging/dmg.rb, '@PAYLOAD@', '@PACKAGE@', '@VERSION@']
33
- output: 'example-app-@TAG@-macos-arm64.dmg'
34
- windows-amd64:
35
- platform: windows
36
- arch: amd64
37
- formats: [inno]
38
- input:
39
- kind: directory
40
- local: dist/windows
41
- native:
42
- command: [ruby, packaging/setup.rb, '@PAYLOAD@', '@PACKAGE@', '@VERSION@']
43
- output: 'example-app-@TAG@-windows-setup.exe'
44
- ```
45
-
46
- Run each target on its own host using `build --version VERSION --target ID`.
47
- Use the normal `aggregate` command to combine complete target results later.
48
- Use the same configuration and `SOURCE_DATE_EPOCH` across jobs.
49
- Since 0.4.0, configurations with AUR/Homebrew recipes can use
50
- `build --defer-recipes` on each host, then `aggregate --finalize-recipes` on
51
- Linux. This avoids requiring the finished DMG before its own build or running
52
- AUR tools on macOS/Windows. The finalizer resolves recipe assets from the
53
- completed package filenames and locally staged external assets. See
54
- [deferred recipe generation](configuration.md#deferred-recipe-generation). No nFPM binary
55
- is required when only native targets are selected; its version remains part of
56
- the configuration for compatibility with mixed Linux/native builds.
57
-
58
- `native.command` is a nonempty argument array, including `@PACKAGE@`, which
59
- resolves to the exact output filename in a fresh directory. `@PAYLOAD@` is an
60
- owned copy of the input directory's contents. A top-level `.app` retains its basename; other input directories use `payload`.
61
- A DMG script should copy the owned input into its own temporary
62
- `Example.app` folder or image staging directory before calling hdiutil. Other existing target tokens apply.
63
- Commands run in the application configuration directory and receive the same
64
- target/version environment as other build hooks.
65
-
66
- DMG requires a macOS binary target; Inno requires a Windows binary target. Both
67
- use one format per target and `input.kind: directory` with `input.local`.
68
- Release-download mode cannot supply a directory: prepare or download/unpack
69
- the app in its build job, then use local mode. `validate` and dry runs do not
70
- execute commands. `doctor` checks the host and recipe executable; the recipe
71
- must check its own additional tools. Mac architecture inspection also needs
72
- Apple's `lipo`. Supported Mac targets are `amd64`, `arm64` and `universal` (both).
73
-
74
- Input copying preserves file modes and internal relative symlinks, including
75
- framework links. Escaping, dangling and special-file entries fail. The initial staged tree must match the original digest. Automatic Apple
76
- signing then signs only that owned copy. The signed staged tree must remain
77
- unchanged after application packaging and `after_package` hooks. Package only this staged input; do not read another application
78
- build from a global location. Recipes should preserve existing destinations,
79
- clean only their own temporary files and use argument arrays for subprocesses.
80
-
81
- The command must create exactly its declared `.dmg` or `.exe` file. The adapter
82
- checks a UDIF trailer or PE container respectively. This is a container check,
83
- not proof of a valid installer, signature or application. The existing `after_package` hook runs before automatic Apple DMG signing,
84
- notarization and stapling, all before the final hash is recorded. Remove redundant
85
- Apple signing/notarization hooks when enabling automatic credentials. Other
86
- application-specific output hooks remain supported. Do not modify a package after building its manifest: signature
87
- stapling changes bytes and must run inside that hook if the manifest is to verify.
88
-
89
- Applications should invoke hdiutil's verification, platform signature checks and
90
- their normal installer compiler checks in their recipes. Preserve native numeric
91
- version ordering across alpha and stable releases; a SemVer suffix cannot be
92
- passed directly to a numeric Windows/macOS version field. The gem does not infer
93
- that policy from an application's release numbering.
94
-
95
- ## Prerelease policy
96
-
97
- `release.prereleases: true` explicitly enables `MAJOR.MINOR.PATCH-alpha.N`,
98
- `-beta.N` and `-rc.N`, with a positive sequence number and no build suffix.
99
- Default/legacy commands continue to require stable versions. Preview builds
100
- support DEB, RPM, DMG and Inno only and cannot contain downstream recipes.
101
- nFPM's normal SemVer conversion produces, for example, `1.2.3~alpha.1` in DEB/RPM;
102
- overriding that prerelease or disabling conversion is rejected. Other package
103
- formats need their own reviewed version policy before being enabled.
104
-
105
- Preview publication only attaches to an existing GitHub release marked as a
106
- prerelease. It never creates a release or changes one from stable to prerelease.
107
- All configured targets must be aggregated and their hashes must verify first.
108
- This opt-in cannot affect applications still pinned to the published 0.2.0 gem.
109
-
110
- ## Acceptance scope
111
-
112
- `ruby -Ilib test/native_acceptance.rb NEW_DIRECTORY` builds a small real native
113
- executable and packages alpha 1, alpha 2 and stable versions. It installs into an
114
- owned disposable directory, checks the executable/version and model fixture,
115
- rolls back to alpha 1 and removes the installation. Mac images are attached
116
- read-only and detached; Windows uses a unique per-user fixture identity and
117
- uninstaller. On Windows, run with a C compiler environment and set
118
- `NATIVE_PACKAGES_ISCC` to the actual Inno compiler path.
119
-
120
- These are gem fixtures, not application installation evidence. They do not
121
- exercise a DJ library, USB export, licensing, notarization or OS-store acceptance.
122
- The generated application build manifest continues to say `installation:
123
- not-tested`; do not turn that into a success claim merely because gem CI passed.
124
-
125
- The [2026-09-13 native record](acceptance/0.3.0-native.json) records successful
126
- DMG lifecycle checks on an ARM64 Mac and Inno lifecycle checks on Windows x64.
127
- Both covered alpha 1 → alpha 2 → stable → alpha 1 and final removal, preserving
128
- the fixture model and exact executable bytes. The native Mac run exposed the
129
- SSH-locale command-output bug, fixed before the successful run. Inno Setup
130
- 6.7.3's official installer was verified against its SHA-256 and Pyrsys B.V.
131
- signature; fixtures compiled with MSVC 14.51. Linux passed 49 tests and 287
132
- assertions, including all existing package formats; the isolated gem install
133
- and build check passed. These local results precede hosted CI for this version.
134
-
135
- References: [nFPM version conversion](https://nfpm.goreleaser.com/docs/configuration/),
136
- [Inno command-line compiler](https://jrsoftware.org/ishelp/topic_compilercmdline.htm).
5
+ [macOS and Windows installers](_guides/native-recipes.md).