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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c07643e9e68f0b147f4e0e53867fb60bb19364460e8b8959aae3cb590cc495e
4
- data.tar.gz: e7bc9be87ac919c2f943ad26c9076825c990cc8ffccdbb84afb86ed436caa1af
3
+ metadata.gz: 66eea8a982e99cb22fd0f06318941567630bf486cd78a90be6f119fca9112185
4
+ data.tar.gz: 82acabb4632dd27e51088a8f2148a210cef3505d36f5ca46cee9a599bc5c96ed
5
5
  SHA512:
6
- metadata.gz: fa5823b8ee458ebf4b751dc5693ad5d7d47c356a4a99791a44dda34285aafb89ae60f75ac16ac8a7b0e0d318131ed5d73448e16515e9c52cffb6edd497296cf6
7
- data.tar.gz: 37440431bcf73aec4eee92929f42fa8b42fe37b4b2911c744ee51ebf643bafd7a34ccc56eb74bca492795a5756b4cae2b203def2fb486b8c6c170ee3bd876e14
6
+ metadata.gz: bdb0d4c085aa2029bfd5fab260a028660a3c63ed0c87841700cca32c41db291394aa71c7ea73b287d862a8f86eceaba02ee4259ac9b64d13c78c0fa144a7060d
7
+ data.tar.gz: b3700e1f354a72f46261a56817e01d186bb853a15dd5a98f01968adde00b464fc52f6a9b5b9f7cb7f1b089ad03a5096318eccd7d6d73323806b6637dcbafbe24
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,86 @@
1
+ # Contributing
2
+
3
+ ## Run the tests
4
+
5
+ Install Ruby 3.2 or later and the development dependencies:
6
+
7
+ ```sh
8
+ bundle install
9
+ bundle exec ruby -Ilib -e 'Dir["test/*_test.rb"].sort.each { |path| require_relative path }'
10
+ ```
11
+
12
+ Package integration checks use nFPM 2.47.0, a C compiler, `readelf`, and `bsdtar`.
13
+ Tests use temporary directories and local Git repositories. CI also runs
14
+ disposable Linux, macOS, and Windows installation checks. Fixture coverage
15
+ does not replace testing packages for each application.
16
+
17
+ To check the packaged gem and standalone command:
18
+
19
+ ```sh
20
+ gem build native-packages.gemspec
21
+ ruby test/gem_install.rb native-packages-0.7.0.gem
22
+ ```
23
+
24
+ See [Releasing the gem](docs/releasing.md) for publication and
25
+ [CLI design](docs/cli-design.md) for the original design notes. Historical
26
+ acceptance records are under [docs/acceptance](docs/acceptance).
27
+
28
+ ## Work on the documentation
29
+
30
+ The site uses [Jekyll VitePress](https://jekyll-vitepress.dev). Its dependencies
31
+ are separate from the CLI's development bundle:
32
+
33
+ ```sh
34
+ cd docs
35
+ bundle install
36
+ bundle exec jekyll serve --livereload
37
+ ```
38
+
39
+ Open <http://localhost:4000/>. To build and check internal links:
40
+
41
+ ```sh
42
+ bundle exec jekyll build --strict_front_matter --trace
43
+ python3 scripts/check_links.py _site
44
+ ```
45
+
46
+ The generated site is in `docs/_site/` and is ignored by Git and excluded from
47
+ the gem. The source uses the published theme gem; there is no machine-specific
48
+ path dependency. To test changes from a local theme checkout, use Bundler's
49
+ temporary path configuration or a separate Gemfile, and keep that local setup
50
+ out of the committed lockfile.
51
+
52
+ ### Writing a guide
53
+
54
+ Put tutorials in `docs/_guides/` and reference pages in `docs/_reference/`.
55
+ Add `title`, `description`, and `nav_order` to the YAML front matter. The sidebar
56
+ and previous/next links follow that order. New pages appear in the sidebar
57
+ automatically.
58
+
59
+ Start with what the reader will accomplish and what they need. Use a complete
60
+ example, explain unfamiliar terms when they first appear, and show the expected
61
+ result after commands. Keep release history and internal implementation notes
62
+ in the changelog or contributor documentation.
63
+
64
+ Use relative Markdown links such as `[Building packages](building-packages.md)`.
65
+ The [relative-links plugin](https://github.com/benbalter/jekyll-relative-links)
66
+ converts them for the site, while the source remains readable on GitHub.
67
+ Liquid rendering is disabled for page content so GitHub Actions expressions
68
+ such as `${{ github.ref_name }}` remain literal in examples.
69
+
70
+ ### Deployment
71
+
72
+ The documentation workflow builds the site and checks links on relevant pull
73
+ requests and pushes. Pushes to `main` also deploy the checked artifact through
74
+ GitHub Pages. To enable the first deployment, select **GitHub Actions** under
75
+ the repository's **Settings → Pages → Build and deployment → Source**.
76
+ See [GitHub's custom workflow setup](https://docs.github.com/en/pages/getting-started-with-github-pages/using-custom-workflows-with-github-pages).
77
+
78
+ The site is published at `https://native-packages.dev/`. GitHub Pages uses
79
+ `native-packages.dev` as the custom domain, with HTTPS enforced. The Jekyll
80
+ configuration uses that URL and an empty `baseurl` so pages and assets are
81
+ served from the domain root.
82
+
83
+ If hosting at a different location, update the Pages custom domain and `url`
84
+ in `docs/_config.yml`. For hosting under a path, also update `baseurl` and the
85
+ link-check command in the workflow. You can preview another base path with
86
+ `bundle exec jekyll build --baseurl /your-path`.
data/README.md CHANGED
@@ -1,151 +1,82 @@
1
+ <p align="center">
2
+ <img src="docs/assets/images/logo.svg" alt="native-packages logo" width="128" height="128">
3
+ </p>
4
+
1
5
  # native-packages
2
6
 
3
- Build native distribution packages with [nFPM](https://nfpm.goreleaser.com/), generate distribution recipes and publish updates from one project configuration.
7
+ Turn your built application into packages people can install.
4
8
 
5
- Applications keep their build scripts, installation assets and native recipes. This gem shares the packaging and downstream repository automation, with no runtime gem dependencies.
9
+ Describe your app's files and supported platforms in one YAML file. Then build
10
+ Linux packages, macOS disk images, or Windows installers, upload them to a
11
+ GitHub release, and update distribution recipes such as AUR packages and
12
+ Homebrew casks.
6
13
 
7
- ## Install and build
14
+ You bring the compiled app. native-packages handles packaging and release updates.
8
15
 
9
- ```sh
10
- gem install native-packages
11
- ```
16
+ [Documentation](https://native-packages.dev/)
12
17
 
13
- Install nFPM 2.47.0 separately for local use; the reusable CI workflow installs it for you. Ruby 3.2 or later is required.
18
+ ## Get started
14
19
 
15
- From an application directory:
20
+ Install with Ruby 3.2 or later:
16
21
 
17
22
  ```sh
18
- native-packages init
19
- # Edit native-packages.yaml: metadata, inputs, dependencies and targets.
20
- native-packages doctor
21
- native-packages build --version 1.2.3
23
+ gem install native-packages
22
24
  ```
23
25
 
24
- `init --interactive` offers guided setup. The default generates a Linux amd64 template, using available Cargo/Git metadata. It does not overwrite existing configuration. Applications need no Gemfile, lockfile or Ruby wrapper. Bundler remains available if preferred.
25
-
26
- ## Configuration
27
-
28
- The [example](examples/native-packages.yaml) is a complete configuration for a static Linux application. A typical project contains:
26
+ From your application directory, create a configuration:
29
27
 
30
- ```text
31
- native-packages.yaml
32
- packaging/ # native recipes, services, icons, etc. when needed
33
- ```
34
-
35
- Use nFPM's existing metadata, contents, dependencies, scripts and format overrides under `nfpm`. Define inputs and output formats per target:
36
-
37
- ```yaml
38
- targets:
39
- linux-amd64:
40
- platform: linux
41
- arch: amd64
42
- libc: static
43
- formats: [deb, rpm, archlinux]
44
- input:
45
- local: dist/my-app-linux-amd64.tar.gz
46
- release_asset: my-app_@VERSION@_linux_amd64.tar.gz
28
+ ```sh
29
+ native-packages init --interactive
47
30
  ```
48
31
 
49
- `build` creates all configured outputs. `--target ID` and `--format FORMAT` select a subset; repeat either option for several values. A missing selected target input fails the build. `publish --target ID` requires
50
- every format for exactly the requested targets, while publication without a
51
- selection still requires all configured targets.
52
-
53
- Inputs support `kind: archive` (default), `directory` or `file`. Paths resolve from the configuration directory. Targets can add `nfpm` overrides; maps merge recursively and arrays replace. `nfpm` can also reference a separate YAML file. `.yml` and `--config FILE` are supported.
54
-
55
- Linux binary targets declare `libc: glibc`, `musl` or `static`. The tool inspects ELF architecture, libc and required libraries without executing the binaries. Known DEB/RPM dependencies are inferred; additional mappings belong under `libraries`. Other formats require explicit dependencies when external libraries are linked. Runtime-loaded libraries and supported distribution baselines still need maintainer declarations and testing.
56
-
57
- `kind: data` allows packages with no executable; `kind: source` is reserved for SRPM sources/specs. Windows targets use PE architecture inspection. Input archive symlinks are currently rejected; represent installed symlinks with nFPM's `type: symlink` contents.
58
-
59
- See [configuration and commands](docs/configuration.md) for tokens, release assets, hooks, version selection and publishing, and [platform coverage](docs/platforms.md) for each format's requirements.
60
-
61
- Version 0.3 adds [native DMG and Inno recipes](docs/native-recipes.md). These run
62
- the application's existing packaging commands on macOS or Windows, using the
63
- same verified build manifests as Linux packages. Native recipes consume prepared
64
- directories and need no nFPM installation. The gem checks Mach-O/PE architecture,
65
- preserves safe internal bundle links and hashes the output after signing hooks.
66
- With complete Apple credentials, macOS DMG builds automatically sign their owned
67
- app copy, notarize the image, staple and validate its ticket before recording
68
- checksums. `notarize-macos INPUT --output OUTPUT` prepares signed, notarized
69
- portable code for an application-owned archive. See [Apple notarization](docs/apple-notarization.md).
70
- App compilation, installer policy and signing identities stay in the application
71
- repository.
32
+ The setup creates `native-packages.yaml` with a Linux x86-64 starting point.
33
+ Review the app's metadata, the path to your compiled files, and the package
34
+ formats you want. The [getting started guide](docs/_guides/getting-started.md)
35
+ walks through a complete example and the required packaging tools.
72
36
 
73
- Preview package versions are explicit: set `release.prereleases: true` to build
74
- `1.2.3-alpha.N`, `-beta.N` or `-rc.N` for DEB/RPM/DMG/Inno. Other formats and
75
- downstream recipe publication remain stable-only. Uploads require an existing
76
- GitHub release already marked as a prerelease.
77
-
78
- The [all-formats example](examples/native-packages-all-formats.yaml) shows separate Linux, OpenWrt, Windows and source inputs, including MSIX identity/assets and an SRPM source/spec layout.
79
-
80
- ## Release inputs and publication
81
-
82
- Build from local files before publishing an application release, or consume an existing release:
37
+ Check your setup and build:
83
38
 
84
39
  ```sh
85
- native-packages build --release v1.2.3
86
- native-packages publish --from dist/packages/1.2.3 --to github
40
+ native-packages doctor
41
+ native-packages build --version 1.2.3
87
42
  ```
88
43
 
89
- Release mode verifies the declared binary assets against the release checksum file. Source assets outside that list may explicitly use `checksummed: false`. Local builds do not need a GitHub release or credentials. An optional target `before_build` argument array invokes the application's existing build script once; release mode skips it.
90
-
91
- Outputs include packages, prepared recipes, checksums and `build.json`. Publication verifies their hashes, configuration identity and complete target set. Partial builds can be combined with `aggregate DIR... --output DIRECTORY`. Native filenames come from nFPM.
92
-
93
- Since 0.4.0, `build --defer-recipes` lets each platform package its
94
- own inputs without acquiring global recipe assets or requiring AUR tools.
95
- Then `aggregate --finalize-recipes` generates the downstream recipes once,
96
- using hashes of the completed packages. This allows a Homebrew cask to reference
97
- the DMG being built in the same release. Deferred builds cannot be published. Native prerelease jobs may defer the
98
- stable recipes in a shared configuration; those recipes remain stable-only.
99
- See [deferred recipe generation](docs/configuration.md#deferred-recipe-generation)
100
- for the finalizer's inputs and checks.
101
-
102
- Optional `repositories` and `templates` sections replace the old separate registries. Existing `stage`, `diff`, `publish TARGET` and `status` commands support reviewed downstream updates. AUR uses PKGBUILD/`.SRCINFO`; Homebrew uses formulae/casks. Each destination has an independent ignored Git clone, with no application submodules or extra remotes. Native source repositories still apply their own validation and review.
44
+ Your packages are in `dist/packages/1.2.3/`, together with checksums and a build
45
+ record. Local builds work without a GitHub release or credentials.
103
46
 
104
- ## GitHub Actions
47
+ ## What can I build?
105
48
 
106
- After publishing application binaries and checksums, call the reusable workflow from the same released tool version:
49
+ | Platform | Outputs |
50
+ | --- | --- |
51
+ | Linux | DEB, RPM, Arch Linux packages, Alpine APK, IPK, and source RPM |
52
+ | macOS | DMG, using your packaging script; optional Apple signing and notarization |
53
+ | Windows | MSIX, or Inno Setup installers using your packaging script |
107
54
 
108
- ```yaml
109
- packaging:
110
- needs: release
111
- permissions:
112
- contents: write
113
- uses: crmne/native-packages/.github/workflows/package.yml@v0.6.0
114
- with:
115
- version: ${{ github.ref_name }}
116
- publish: true
117
- secrets: inherit
118
- ```
119
-
120
- Pin the corresponding commit SHA for an immutable workflow reference. With no version, the workflow validates configuration only. With a version, it installs the configured gem and nFPM, builds packages and uploads an Actions artifact. `publish: true` attaches packages to the existing release.
121
-
122
- Separate configurations have independent concurrency groups. A workflow can validate its stable, alpha and macOS configurations without one queued call cancelling another. The released `v0.5.0` workflow predates this fix; serialize multiple calls with `needs` when using that tag or its commit.
123
-
124
- To consume an Actions artifact instead, set `source-artifact` and, if necessary, `source-directory` (default `dist`). Its files must match the local input paths in the configuration. This workflow packages on Linux, including MSIX creation from Windows binaries; native application builds and platform-specific signing jobs can use the CLI separately.
55
+ Each target needs files built for that platform. DMG and Inno builds run on
56
+ macOS and Windows respectively. See [supported platforms](docs/_reference/platforms.md)
57
+ for prerequisites and distribution recipes.
125
58
 
126
- AUR publication additionally requires `PUBLISH_AUR=true`, `AUR_SSH_KEY` and `AUR_KNOWN_HOSTS`. Homebrew publication requires `PUBLISH_HOMEBREW=true` and `HOMEBREW_TAP_GITHUB_TOKEN`. Keep existing GoReleaser publishers for destinations they already own.
59
+ ## Guides
127
60
 
128
- ## Migration and development
61
+ Start with [getting started](docs/_guides/getting-started.md).
129
62
 
130
- ```sh
131
- native-packages migrate --dry-run
132
- native-packages migrate
133
- ```
63
+ - [Building packages](docs/_guides/building-packages.md) — add files, dependencies, and more targets.
64
+ - [Publishing a release](docs/_guides/publishing.md) — build from release assets and upload packages.
65
+ - [GitHub Actions](docs/_guides/github-actions.md) — add packaging to your release workflow.
66
+ - [macOS and Windows installers](docs/_guides/native-recipes.md) — connect your native packaging scripts.
67
+ - [Apple signing and notarization](docs/_guides/apple-notarization.md) — prepare macOS downloads for distribution.
68
+ - [Release signatures and attestations](docs/_guides/release-signing.md): authorize updater downloads and identify their build workflow.
69
+ - [AUR, Homebrew, and other repositories](docs/_guides/distribution-recipes.md) — generate and publish recipes.
134
70
 
135
- Migration combines `packaging/project.yml`, its nFPM definition and repository registry while preserving templates and existing files. Compare generated outputs before removing packaging-only Gemfiles or wrappers. App-specific Ruby generators, such as Hyprmoncfg's Nix/source-package logic, require a manual adapter; the generic migrator does not rewrite them. Existing v0.1 configurations and commands remain available. See the [legacy guide](docs/legacy.md).
71
+ For a particular option or error, see the [configuration reference](docs/_reference/configuration.md),
72
+ [command reference](docs/_reference/commands.md), and [troubleshooting guide](docs/_reference/troubleshooting.md).
136
73
 
137
- ```sh
138
- bundle install
139
- bundle exec ruby -Ilib -e 'Dir["test/*_test.rb"].sort.each { |path| require_relative path }'
140
- gem build native-packages.gemspec
141
- ruby test/gem_install.rb native-packages-0.6.0.gem
142
- ```
74
+ ## Contributing
143
75
 
144
- Tests build real packages, inspect their payloads and exercise repository publication against local Git fixtures. CI additionally runs disposable Linux install/upgrade/remove checks, SRPM rebuilds and Windows MSIX acceptance. Runtime build manifests report installation as `not-tested`: CI fixture coverage is not a substitute for testing each application's packages.
76
+ See [Contributing](CONTRIBUTING.md) for development, tests, and running the
77
+ documentation site locally. Upgrading an older setup? Read
78
+ the [`migrate` command reference](docs/_reference/commands.md#migrate).
145
79
 
146
- The [design document](docs/cli-design.md) records the agreed direction. [Gem release setup](docs/releasing.md) explains the RubyLLM-style token setup and GitHub release workflow.
80
+ ## License
147
81
 
148
- For one configuration spanning native hosts, select the Linux target IDs in the
149
- reusable workflow's `targets` input. Native release jobs use the same config
150
- with `build --target macos-universal --defer-recipes` on the Mac. See
151
- [one configuration across native hosts](docs/configuration.md#one-configuration-across-native-hosts).
82
+ [MIT](LICENSE)
data/docs/404.md ADDED
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Page not found
3
+ description: Find the guide you were looking for in the native-packages documentation.
4
+ permalink: /404.html
5
+ layout: home
6
+ noindex: true
7
+ ---
8
+
9
+ # Page not found
10
+
11
+ Try the search above, or start with
12
+ [your first package](_guides/getting-started.md).
@@ -0,0 +1,116 @@
1
+ ---
2
+ title: Apple signing and notarization
3
+ description: Configure Apple credentials, automatically sign and notarize DMGs, and prepare portable macOS archives.
4
+ nav_order: 6
5
+ ---
6
+
7
+ # Apple signing and notarization
8
+
9
+ native-packages can sign your macOS app and submit it to Apple's notarization
10
+ service before recording the package checksum. For a DMG, it also attaches
11
+ Apple's approval ticket to the image, a step called **stapling**.
12
+
13
+ This guide assumes you already have a working [DMG target](native-recipes.md).
14
+ It also covers portable downloads such as a command-line app distributed as a
15
+ `.tar.gz` archive.
16
+
17
+ ## 1. Set up your Apple credentials
18
+
19
+ You need a Developer ID Application certificate and its private key, an Apple
20
+ Developer Program team, and an app-specific password for the Apple Account
21
+ used for notarization.
22
+
23
+ Export the certificate and private key as a password-protected PKCS#12 (`.p12`)
24
+ file. Base64-encode that file for `APPLE_CERTIFICATE_P12`, and configure all six
25
+ values as environment variables in the macOS release job:
26
+
27
+ | Variable | Value |
28
+ | --- | --- |
29
+ | `APPLE_CERTIFICATE_P12` | Base64-encoded `.p12` certificate and private key. |
30
+ | `APPLE_CERTIFICATE_PASSWORD` | Password protecting the `.p12` export. |
31
+ | `APPLE_SIGNING_IDENTITY` | Exact identity, such as `Developer ID Application: Your Name (TEAMID)`. |
32
+ | `APPLE_ID` | Apple Account email. |
33
+ | `APPLE_TEAM_ID` | Developer Program Team ID. |
34
+ | `APPLE_APP_PASSWORD` | Apple Account app-specific password. |
35
+
36
+ Store the values as CI secrets and expose them to your macOS release job.
37
+ The tool reads environment variables; it does not retrieve secrets for you.
38
+ Apple documents [Developer ID certificates](https://developer.apple.com/help/account/certificates/create-developer-id-certificates/)
39
+ and [notarization](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution).
40
+
41
+ With none of these variables set, builds remain unsigned. With all six set,
42
+ signing and notarization are automatic. An incomplete set fails with the names
43
+ of the missing variables. Linux and Windows targets ignore these variables.
44
+
45
+ ## 2. Build the DMG
46
+
47
+ Run the normal command on macOS:
48
+
49
+ ```sh
50
+ native-packages build --version 1.2.3 --target macos-arm64 --output dist/macos-packages
51
+ ```
52
+
53
+ The build performs these steps:
54
+
55
+ 1. Copies and checks your prepared app.
56
+ 2. Signs code inside the copy, working from nested code outward.
57
+ 3. Runs your DMG script with the signed copy as `@PAYLOAD@`.
58
+ 4. Runs any `after_package` hook.
59
+ 5. Signs the DMG, submits it to Apple, and waits for acceptance.
60
+ 6. Staples and validates the ticket, then verifies the image.
61
+ 7. Records the final checksum and notarization result in `build.json`.
62
+
63
+ Your original app directory stays unchanged. The manifest records Apple
64
+ acceptance, the submission ID, and stapling. Failure or timeout prevents a
65
+ completed build from being produced. Submissions can wait up to 30 minutes;
66
+ Apple may continue processing a submission after a timeout.
67
+
68
+ ## 3. Keep your script focused on the image
69
+
70
+ Your DMG script should copy `@PAYLOAD@` with its signatures intact and create
71
+ the declared image. Remove duplicate Apple signing and notarization steps
72
+ from the script or `after_package` hook when adopting the automatic flow.
73
+
74
+ Signing uses a secure timestamp and hardened runtime. Existing entitlements
75
+ and requirements are preserved. Supply the entitlements your app needs in
76
+ its build process; native-packages does not add exceptions for you.
77
+
78
+ ## Prepare a portable archive
79
+
80
+ For a portable executable and its libraries, prepare the complete directory,
81
+ including notices and other runtime files. Then run:
82
+
83
+ ```sh
84
+ native-packages notarize-macos portable-input --output signed/hello-1.2.3-macos-arm64
85
+ tar czf hello-1.2.3-macos-arm64.tar.gz -C signed hello-1.2.3-macos-arm64
86
+ ```
87
+
88
+ The destination must be new and outside the input. This command requires no
89
+ `native-packages.yaml`.
90
+
91
+ With credentials, it signs a copy and submits that code through a temporary
92
+ ZIP. After Apple accepts it, the command staples any `.app` bundles and makes
93
+ the signed directory available. Archive only that returned directory and
94
+ preserve its signed contents.
95
+
96
+ Without credentials, the command copies the input unchanged and reports that
97
+ signing and notarization were skipped.
98
+
99
+ Standalone executables cannot carry a stapled ticket. They rely on Gatekeeper's
100
+ online ticket lookup, so a notarized portable executable does not have the same
101
+ offline behavior as a stapled app or DMG.
102
+
103
+ ## Check the download
104
+
105
+ Test a freshly downloaded package on macOS with Gatekeeper enabled. Also test
106
+ your app's startup, required entitlements, supported macOS versions, and
107
+ upgrade behavior. Apple acceptance is recorded separately from installation
108
+ testing; the build manifest still reports installation as `not-tested`.
109
+
110
+ ## How credentials are handled
111
+
112
+ The tool imports credentials into a temporary keychain. Signing calls under
113
+ the same OS user share a lock while updating keychain search entries. Cleanup
114
+ removes the temporary keychain and its entry while preserving other entries
115
+ and the default keychain. Secret values are excluded from build manifests and
116
+ redacted from tool errors.
@@ -0,0 +1,190 @@
1
+ ---
2
+ title: Building packages
3
+ description: Choose package contents, input files, dependencies, hooks, and build targets.
4
+ nav_order: 2
5
+ ---
6
+
7
+ # Building packages
8
+
9
+ This guide builds on [Getting started](getting-started.md). You will learn how
10
+ to include the rest of your app's files and build for more than one target.
11
+
12
+ ## Choose an input
13
+
14
+ An input is the file or directory containing your compiled app. Paths are
15
+ relative to `native-packages.yaml`, even when you select it with `--config`.
16
+
17
+ | `input.kind` | Use it for | Example `input.local` |
18
+ | --- | --- | --- |
19
+ | `file` | A single executable | `dist/hello` |
20
+ | `directory` | An executable plus supporting files | `dist/linux-amd64` |
21
+ | `archive` (default) | A ZIP or tar archive | `dist/hello-linux-amd64.tar.gz` |
22
+
23
+ For a directory containing `hello`, `LICENSE`, and `hello.desktop`, change the
24
+ target's input to:
25
+
26
+ ```yaml
27
+ input:
28
+ kind: directory
29
+ local: dist/linux-amd64
30
+ ```
31
+
32
+ Those files become `@PAYLOAD@/hello`, `@PAYLOAD@/LICENSE`, and
33
+ `@PAYLOAD@/hello.desktop`. Archives are unpacked without removing a top-level
34
+ folder: if the archive contains `hello-1.2.3/hello`, use
35
+ `@PAYLOAD@/hello-1.2.3/hello` as the source.
36
+
37
+ ## Add installed files
38
+
39
+ List files under `nfpm.contents`. For example:
40
+
41
+ ```yaml
42
+ contents:
43
+ - src: '@PAYLOAD@/hello'
44
+ dst: /usr/bin/hello
45
+ file_info:
46
+ mode: 0755
47
+ - src: '@PAYLOAD@/LICENSE'
48
+ dst: /usr/share/licenses/hello/LICENSE
49
+ file_info:
50
+ mode: 0644
51
+ - src: '@PAYLOAD@/hello.desktop'
52
+ dst: /usr/share/applications/hello.desktop
53
+ - src: packaging/hello.conf
54
+ dst: /etc/hello.conf
55
+ type: config
56
+ ```
57
+
58
+ `0755` makes the executable runnable. `0644` is suitable for ordinary data
59
+ files. `type: config` marks a file as configuration for the package manager.
60
+ Files such as `packaging/hello.conf` can also come directly from your project.
61
+
62
+ For an installed symbolic link, declare it explicitly:
63
+
64
+ ```yaml
65
+ contents:
66
+ - src: /usr/bin/hello
67
+ dst: /usr/bin/hello-cli
68
+ type: symlink
69
+ ```
70
+
71
+ Add that entry to your existing list. It makes `hello-cli` point to `hello`
72
+ after installation. Regular package inputs currently reject symlinks;
73
+ [native macOS and Windows inputs](native-recipes.md) support safe internal links.
74
+
75
+ ## Declare dependencies
76
+
77
+ Linux binaries must declare the C library they were built for:
78
+
79
+ | `libc` | Choose this when |
80
+ | --- | --- |
81
+ | `glibc` | Your executable links to glibc, as on Debian or Fedora. |
82
+ | `musl` | Your executable links to musl, as commonly used on Alpine. |
83
+ | `static` | Your executable has no dynamic interpreter or shared-library dependencies. |
84
+
85
+ native-packages inspects the files without running them. For DEB and RPM it
86
+ adds known library dependencies and a glibc version requirement where needed.
87
+ Declare libraries loaded at runtime and other app requirements yourself.
88
+
89
+ Dependency names can differ by distribution. Put format-specific lists under
90
+ `nfpm.overrides`:
91
+
92
+ ```yaml
93
+ overrides:
94
+ deb:
95
+ depends: [ca-certificates]
96
+ rpm:
97
+ depends: [ca-certificates]
98
+ archlinux:
99
+ depends: [glibc, ca-certificates]
100
+ ```
101
+
102
+ For Arch, Alpine, and IPK, explicitly list external runtime dependencies.
103
+ Check package names against the distribution versions your app supports.
104
+ See [library mappings](../_reference/configuration.md#libraries) for extending
105
+ DEB/RPM dependency detection.
106
+
107
+ ## Add another target
108
+
109
+ A **target** gives a name to one platform, architecture, and input. Several
110
+ formats can share a target if they use the same compatible files.
111
+
112
+ Add this next to `linux-amd64` under `targets` after building an ARM64 executable:
113
+
114
+ ```yaml
115
+ linux-arm64:
116
+ platform: linux
117
+ arch: arm64
118
+ libc: glibc
119
+ formats: [deb, rpm]
120
+ input:
121
+ kind: directory
122
+ local: dist/linux-arm64
123
+ ```
124
+
125
+ Both targets use the shared package metadata and file mappings. A target can
126
+ have its own `nfpm` section to override them. Maps merge; lists replace the
127
+ whole list, so a target-specific `contents` must list all of that target's files.
128
+
129
+ Use a separate musl or static build for Alpine. Changing `formats` alone
130
+ does not change which systems a binary can run on.
131
+
132
+ ## Select what to build
133
+
134
+ Build everything, one target, or one format:
135
+
136
+ ```sh
137
+ native-packages build --version 1.2.3
138
+ native-packages build --version 1.2.3 --target linux-arm64 --output dist/arm64-packages
139
+ native-packages build --version 1.2.3 --format deb --output dist/deb-packages
140
+ ```
141
+
142
+ Repeat `--target` or `--format` to select several values. Each output directory
143
+ must be new. To inspect the plan without running build hooks or downloading
144
+ inputs:
145
+
146
+ ```sh
147
+ native-packages build --version 1.2.3 --dry-run
148
+ ```
149
+
150
+ A selected input must exist when the build reaches that target.
151
+
152
+ ## Run your build script
153
+
154
+ If you want packaging to invoke your existing build script first, add a hook
155
+ to the target:
156
+
157
+ ```yaml
158
+ before_build: [./scripts/build-linux.sh, '@ARCH@']
159
+ ```
160
+
161
+ This runs once per selected target, in the configuration directory, before
162
+ the input is copied. The script must produce the configured input path.
163
+ It also receives `NATIVE_PACKAGES_TARGET` and `NATIVE_PACKAGES_VERSION` as
164
+ environment variables. Builds using `--release` skip this hook.
165
+
166
+ Use `after_package` for steps such as Windows signing. It runs once for each
167
+ package before checksums are recorded:
168
+
169
+ ```yaml
170
+ after_package: [pwsh, -File, packaging/sign.ps1, '@PACKAGE@']
171
+ ```
172
+
173
+ Hooks are argument lists. Put shell pipelines or multiple commands in a script.
174
+ See [hooks and replacement values](../_reference/configuration.md#hooks).
175
+
176
+ ## Packages containing only data or source
177
+
178
+ Use target-level `kind: data` for packages containing configuration or data
179
+ without compiled executables. This is separate from `input.kind`, which says
180
+ how the input is stored.
181
+
182
+ Source RPMs use a separate target with `kind: source`, `formats: [srpm]`,
183
+ and an RPM spec plus its sources. The
184
+ [all-formats example](https://github.com/crmne/native-packages/blob/main/examples/native-packages-all-formats.yaml)
185
+ shows the full layout.
186
+
187
+ ## Next steps
188
+
189
+ Follow [Publishing a release](publishing.md) to share the result, or
190
+ [macOS and Windows installers](native-recipes.md) to add native installer scripts.