native-packages 0.2.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +119 -0
- data/docs/cli-design.md +161 -0
- data/docs/configuration.md +61 -0
- data/docs/legacy.md +123 -0
- data/docs/platforms.md +32 -0
- data/docs/releasing.md +33 -0
- data/examples/native-packages-all-formats.yaml +87 -0
- data/examples/native-packages.yaml +31 -0
- data/examples/packaging/arch/example-app-bin/PKGBUILD.in +18 -0
- data/examples/packaging/nfpm.yml +15 -0
- data/examples/packaging/project.yml +15 -0
- data/examples/packaging/repositories.yml +14 -0
- data/exe/native-packages +5 -0
- data/lib/native_packages/build.rb +306 -0
- data/lib/native_packages/cli.rb +128 -0
- data/lib/native_packages/configuration.rb +155 -0
- data/lib/native_packages/inspection.rb +125 -0
- data/lib/native_packages/project.rb +258 -0
- data/lib/native_packages/repositories.rb +427 -0
- data/lib/native_packages/scaffold.rb +88 -0
- data/lib/native_packages/support.rb +116 -0
- data/lib/native_packages.rb +4 -0
- metadata +65 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0f937a8788833696a7e7f71ae4a2892c9fbd5dc9da1492376155530e0fa349e6
|
|
4
|
+
data.tar.gz: 7dc4b26da615673f0639bdb54344978bc60f54386451e35286e00bb76f8228de
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 6a66d883eb494ac1a0d04311fa09a844a110b88c9fd2e75df1178f4fb79e027fdd694185c15169a705a77b99a62f041e0a9f4415617ff20dc6a1b40aaf457fb5
|
|
7
|
+
data.tar.gz: a0900c282473d8b1b1b1da1855889a2279dcaa8eaddefc7abf7aaa554c6db40435f86aae1def077e189294adc3b1c142247a62fdeefeb9a34073e93abee460fc
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Carmine Paolino
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# native-packages
|
|
2
|
+
|
|
3
|
+
Build native distribution packages with [nFPM](https://nfpm.goreleaser.com/), generate distribution recipes and publish updates from one project configuration.
|
|
4
|
+
|
|
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.
|
|
6
|
+
|
|
7
|
+
## Install and build
|
|
8
|
+
|
|
9
|
+
Version 0.2 is being prepared for RubyGems publication. Until published, build and install the gem from this repository:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
gem build native-packages.gemspec
|
|
13
|
+
gem install ./native-packages-0.2.0.gem
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
After publication, installation is `gem install native-packages`. Install nFPM 2.47.0 separately for local use; the reusable CI workflow installs it for you. Ruby 3.2 or later is required.
|
|
17
|
+
|
|
18
|
+
From an application directory:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
native-packages init
|
|
22
|
+
# Edit native-packages.yaml: metadata, inputs, dependencies and targets.
|
|
23
|
+
native-packages doctor
|
|
24
|
+
native-packages build --version 1.2.3
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`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.
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
The [example](examples/native-packages.yaml) is a complete configuration for a static Linux application. A typical project contains:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
native-packages.yaml
|
|
35
|
+
packaging/ # native recipes, services, icons, etc. when needed
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use nFPM's existing metadata, contents, dependencies, scripts and format overrides under `nfpm`. Define inputs and output formats per target:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
targets:
|
|
42
|
+
linux-amd64:
|
|
43
|
+
platform: linux
|
|
44
|
+
arch: amd64
|
|
45
|
+
libc: static
|
|
46
|
+
formats: [deb, rpm, archlinux]
|
|
47
|
+
input:
|
|
48
|
+
local: dist/my-app-linux-amd64.tar.gz
|
|
49
|
+
release_asset: my-app_@VERSION@_linux_amd64.tar.gz
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`build` creates all configured outputs. `--target ID` and `--format FORMAT` select a subset; repeat either option for several values. A missing target input fails the build.
|
|
53
|
+
|
|
54
|
+
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.
|
|
55
|
+
|
|
56
|
+
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.
|
|
57
|
+
|
|
58
|
+
`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.
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
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.
|
|
63
|
+
|
|
64
|
+
## Release inputs and publication
|
|
65
|
+
|
|
66
|
+
Build from local files before publishing an application release, or consume an existing release:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
native-packages build --release v1.2.3
|
|
70
|
+
native-packages publish --from dist/packages/1.2.3 --to github
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
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.
|
|
74
|
+
|
|
75
|
+
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.
|
|
76
|
+
|
|
77
|
+
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.
|
|
78
|
+
|
|
79
|
+
## GitHub Actions
|
|
80
|
+
|
|
81
|
+
After publishing application binaries and checksums, call the reusable workflow from the same released tool version:
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
packaging:
|
|
85
|
+
needs: release
|
|
86
|
+
permissions:
|
|
87
|
+
contents: write
|
|
88
|
+
uses: crmne/native-packages/.github/workflows/package.yml@v0.2.0
|
|
89
|
+
with:
|
|
90
|
+
version: ${{ github.ref_name }}
|
|
91
|
+
publish: true
|
|
92
|
+
secrets: inherit
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This reference becomes available when v0.2.0 is tagged. 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.
|
|
96
|
+
|
|
97
|
+
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.
|
|
98
|
+
|
|
99
|
+
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.
|
|
100
|
+
|
|
101
|
+
## Migration and development
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
native-packages migrate --dry-run
|
|
105
|
+
native-packages migrate
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
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).
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
bundle install
|
|
112
|
+
bundle exec ruby -Ilib -e 'Dir["test/*_test.rb"].sort.each { |path| require_relative path }'
|
|
113
|
+
gem build native-packages.gemspec
|
|
114
|
+
ruby test/gem_install.rb native-packages-0.2.0.gem
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
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.
|
|
118
|
+
|
|
119
|
+
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.
|
data/docs/cli-design.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Proposal: an installable CLI with one project configuration
|
|
2
|
+
|
|
3
|
+
Status: accepted, 2026-09-13. Publishing was subsequently aligned with RubyLLM: GitHub release publication triggers the workflow, using `RUBYGEMS_AUTH_TOKEN`. The original Trusted Publishing proposal below is superseded by that decision. The v0.2 implementation follows this design. See the current [configuration reference](configuration.md) and [release setup](releasing.md) for the implemented interface and publication requirements. This document records the original design; it does not describe v0.1.0.
|
|
4
|
+
|
|
5
|
+
The proposed interface is `gem install native-packages`, `native-packages init`, and `native-packages build`. A project normally needs one `native-packages.yaml` file. The tool should expose every nFPM packager and use the application's declared inputs to decide what to build.
|
|
6
|
+
|
|
7
|
+
## Why v0.1 stops at DEB/RPM
|
|
8
|
+
|
|
9
|
+
Version 0.1 extracted working automation from our applications. Its implementation still assumes Linux release archives, amd64/arm64, and DEB/RPM dependency names. These assumptions occur in `Project#binary_packages`, `Project#runtime_dependencies`, and the release-upload filename check in `Support#upload_assets`. It also requires a published GitHub release before packaging and loads configuration from several fixed paths.
|
|
10
|
+
|
|
11
|
+
Those are implementation limits, not a desirable product boundary. Changing the format loop alone would still reject Windows inputs, attach incorrect dependency metadata, and reject the resulting filenames during publication.
|
|
12
|
+
|
|
13
|
+
The repository already has a gemspec and an executable. The Git dependency and application Gemfiles were a distribution shortcut before RubyGems publication. They should become optional for consumers; the shared repository keeps its own development Gemfile and lockfile.
|
|
14
|
+
|
|
15
|
+
## Installation and version selection
|
|
16
|
+
|
|
17
|
+
After the proposed version is published:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
gem install native-packages
|
|
21
|
+
native-packages init
|
|
22
|
+
native-packages doctor
|
|
23
|
+
native-packages build --version 1.2.3
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`gem install` supplies the `native-packages` executable through RubyGems. Application repositories need no Ruby wrapper script, Gemfile, lockfile, or vendored library. Existing Ruby projects can continue to use Bundler if they prefer its dependency resolution. [RubyGems publishing](https://guides.rubygems.org/publishing/)
|
|
27
|
+
|
|
28
|
+
Use exact tool versions in the project configuration. CI reads those versions and installs them; the local CLI checks the running version and prints the matching install/invocation command when it differs. RubyGems can select an installed executable version with syntax such as `native-packages _0.2.0_ build`. Do not silently change the global installation or fall back to the latest gem. No new application lockfile is needed while the gem has no runtime gem dependencies. If dependencies are introduced, revisit the reproducibility contract rather than pretending a gem version locks its entire dependency tree.
|
|
29
|
+
|
|
30
|
+
nFPM remains an external executable. RubyGems does not install that Go program as a Ruby dependency. Local users install it once using an existing supported installation method; `doctor` checks it. The shared CI installs the pinned nFPM version and only the additional tools needed by the selected targets. Avoid writing a second package manager or bundling copies of nFPM for every host into the gem.
|
|
31
|
+
|
|
32
|
+
Publish the gem from this repository's release workflow using RubyGems Trusted Publishing. Configure ownership of the gem name and a pending trusted publisher for the first release, then publish tested tags. This is separate from publishing application packages. [RubyGems Trusted Publishing](https://guides.rubygems.org/trusted-publishing/)
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
| Command | Proposed behavior |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `init` | Detect basic project metadata and write one default configuration. Print fields that still need editing. |
|
|
39
|
+
| `init --interactive` | Ask for missing package identity, input locations and desired outputs, then write the same configuration. |
|
|
40
|
+
| `doctor` | Check configuration, required executables and version compatibility. Report actionable missing requirements. |
|
|
41
|
+
| `validate` | Check configuration and template structure without downloading artifacts, running application build commands or publishing. |
|
|
42
|
+
| `build` | Use local inputs, render configured recipes and build every configured package target. |
|
|
43
|
+
| `build --release v1.2.3` | Obtain the declared assets from an existing release, verify their checksums, then run the same build path. |
|
|
44
|
+
| `build --target linux-amd64` | Build a named target; repeat the option to select several. |
|
|
45
|
+
| `build --format apk` | Build that format across configured targets that explicitly include it. Fail if none match. |
|
|
46
|
+
| `build --dry-run` | Show selected inputs, commands and outputs without running commands or downloading inputs. |
|
|
47
|
+
| `publish --from dist/packages/1.2.3 --to github,aur` | Publish a previously built result to named configured destinations. |
|
|
48
|
+
| `status` | Report downstream versions and pending submissions. |
|
|
49
|
+
|
|
50
|
+
Keep the existing `stage`, `diff` and submission commands for maintainers who need to review native recipes before publication. Retain existing command forms during migration.
|
|
51
|
+
|
|
52
|
+
`init` generates a template by default, so it also works without a terminal. Interactive prompts are optional and never run in CI. Infer metadata from Git and supported manifests only where unambiguous; never invent dependency names, credentials, publisher identities or unsupported platforms. Do not overwrite existing configuration. Offer migration when the old layout is detected.
|
|
53
|
+
|
|
54
|
+
`build` means building distribution packages. It normally consumes files made by the application's existing build. An optional `before_build` command, expressed as an argument array, can call an existing script once per selected target. This lets `build` perform the complete local sequence without adding Rust, Go, CMake or cross-compilation implementations to this project. Release-download mode skips that source-build command. Other commands do not execute it.
|
|
55
|
+
|
|
56
|
+
An omitted version is resolved only from an exact supported release tag at HEAD; otherwise request `--version`. `--release` supplies the version itself and conflicts with a different explicit version. Start with the current stable `vMAJOR.MINOR.PATCH` convention; prerelease publication and format-specific version conversions need a separate explicit policy.
|
|
57
|
+
|
|
58
|
+
## One YAML file
|
|
59
|
+
|
|
60
|
+
Use `native-packages.yaml` to match the gem and command name. Accept `.yml` as an alias and an explicit `--config PATH`; error if discovery finds both. Resolve relative paths from the configuration directory. Advanced projects can keep native templates and assets under `packaging/`.
|
|
61
|
+
|
|
62
|
+
An illustrative configuration for an application with a static Linux binary:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
schema: 1
|
|
66
|
+
tool:
|
|
67
|
+
version: "0.2.0" # Proposed release, not currently published.
|
|
68
|
+
nfpm: "2.47.0"
|
|
69
|
+
|
|
70
|
+
nfpm:
|
|
71
|
+
name: example-app
|
|
72
|
+
description: An example desktop utility
|
|
73
|
+
maintainer: Example Maintainer <maintainer@example.org>
|
|
74
|
+
homepage: https://github.com/example/example-app
|
|
75
|
+
license: MIT
|
|
76
|
+
contents:
|
|
77
|
+
- src: "@PAYLOAD@/example-app"
|
|
78
|
+
dst: /usr/bin/example-app
|
|
79
|
+
file_info:
|
|
80
|
+
mode: 0755
|
|
81
|
+
|
|
82
|
+
targets:
|
|
83
|
+
linux-amd64:
|
|
84
|
+
platform: linux
|
|
85
|
+
arch: amd64
|
|
86
|
+
libc: static
|
|
87
|
+
formats: [deb, rpm, archlinux]
|
|
88
|
+
input:
|
|
89
|
+
local: dist/example-app-linux-amd64.tar.gz
|
|
90
|
+
release_asset: example-app_@VERSION@_linux_amd64.tar.gz
|
|
91
|
+
|
|
92
|
+
release:
|
|
93
|
+
repository: example/example-app
|
|
94
|
+
checksums: checksums.txt
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Only one target is shown. Static does not imply a complete desktop application has no runtime dependencies; add its actual dependencies, assets and scripts. A second target can use the same package definition with different inputs or per-target nFPM fields.
|
|
98
|
+
|
|
99
|
+
`nfpm` uses nFPM's existing keys for package metadata, contents, scripts, dependencies, overrides and signing. Avoid renaming them into our own packaging language. Target-specific `nfpm` mappings override shared mappings: maps merge recursively, lists replace in full, and scalar values replace. Resolve release version, architecture and platform once; reject conflicting declarations rather than silently overriding them. nFPM remains responsible for its format-specific semantics.
|
|
100
|
+
|
|
101
|
+
The outer schema owns only tool versions, input acquisition, targets, optional build commands, templates and destinations. Use a small documented token set, extending the existing `@VERSION@`, `@PAYLOAD@` and `@ARCH@` syntax. Do not add general expression evaluation. Missing tokens fail with their configuration location.
|
|
102
|
+
|
|
103
|
+
An input can be a local file, directory or archive. Release acquisition is optional and declares asset filenames plus a checksum source. Additional assets used only by recipes, such as source archives and macOS DMGs, can be declared without a binary-package target. Optional `templates` and `repositories` sections incorporate the existing template and downstream mappings; omitted sections mean there are none. A simple project needs no empty repository registry or separate nFPM file. A documented file-reference form can preserve larger configurations without making it the default.
|
|
104
|
+
|
|
105
|
+
Recommend YAML for this version. A Ruby DSL would introduce another API to maintain and require executing configuration just to inspect it. Existing build scripts and native Homebrew Ruby recipes already cover the immediate need for code. Add a Ruby configuration frontend only if concrete applications cannot be represented cleanly by this model.
|
|
106
|
+
|
|
107
|
+
## Wire all nFPM formats
|
|
108
|
+
|
|
109
|
+
Expose all packagers supported by the pinned nFPM version. Use explicit target declarations, not a global attempt to package one archive into every format. `build` builds all configured outputs; missing or incompatible inputs fail instead of being silently skipped.
|
|
110
|
+
|
|
111
|
+
The installed nFPM 2.47.0 CLI enumerates **seven** packagers, including `srpm`, which the original README's list omitted. It exposes format selection through the same `package --packager` command. [nFPM command implementation](https://github.com/goreleaser/nfpm/blob/v2.47.0/internal/cmd/package.go)
|
|
112
|
+
|
|
113
|
+
| Packager | Target declaration and validation needed |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `deb` | Appropriate Linux payload, dependencies and installation paths. Preserve current coverage. |
|
|
116
|
+
| `rpm` | Same, using the intended RPM distribution's dependency names and baseline. |
|
|
117
|
+
| `archlinux` | Arch-compatible payload and metadata. This creates a downloadable package; AUR publication continues to use PKGBUILD and `.SRCINFO`. |
|
|
118
|
+
| `apk` | Payload and dependencies for the chosen Alpine target. Select musl/static inputs where appropriate; never reinterpret a glibc payload as musl merely by changing the suffix. |
|
|
119
|
+
| `ipk` | Payload for an explicitly named device/distribution ABI and architecture. Do not assume that a desktop archive is suitable. |
|
|
120
|
+
| `msix` | Windows payload and package layout, publisher identity, application entries and image assets. Run PE inspection instead of Linux ELF inspection. Signing uses the format's native configuration. |
|
|
121
|
+
| `srpm` | Source/spec payload with a separate source target. Do not package an executable under a source-package label. Validate rebuildability through RPM tooling. |
|
|
122
|
+
|
|
123
|
+
nFPM provides format-specific metadata and override fields; the shared layer should pass them through. MSIX needs Windows-specific identity and application settings. [nFPM configuration](https://nfpm.goreleaser.com/docs/configuration/)
|
|
124
|
+
|
|
125
|
+
nFPM's SRPM implementation sets source-package metadata and writes the supplied contents. Our assessment is that a useful source package still requires a spec and suitable sources, with native rebuild testing. Generating that recipe remains application-owned. [nFPM RPM/SRPM implementation](https://github.com/goreleaser/nfpm/blob/v2.47.0/rpm/rpm.go)
|
|
126
|
+
|
|
127
|
+
Use a small table of known formats and validation capabilities, tied to the supported nFPM version. Adding a packager should not require another full packaging implementation. New upstream formats should produce a clear unsupported-version diagnostic until their dispatch and checks are added; do not scrape human-readable help at runtime as a compatibility API.
|
|
128
|
+
|
|
129
|
+
Remove hardcoded Rust target triples. Carry OS, architecture, libc/ABI and any compiler target string explicitly. Use nFPM's native architecture mapping, including format overrides. Binary inspectors must handle their supported architecture and endianness correctly and report validation coverage separately from the backend's ability to create a package. Data/source packages do not need an executable. An unimplemented inspection path cannot silently count as successful validation.
|
|
130
|
+
|
|
131
|
+
Keep dependency handling modest. Preserve the existing verified DEB/RPM mappings, make inference format-aware, and allow explicit declarations for other targets. Do not invent a universal distro dependency database. Inspect the selected package contents, including bundled libraries, and document that runtime-loaded dependencies still need declarations.
|
|
132
|
+
|
|
133
|
+
## Build results and publishing
|
|
134
|
+
|
|
135
|
+
Let nFPM choose conventional package filenames by giving it a fresh output directory. Do not manufacture extensions such as `.archlinux` or `.srpm`. Separate target output directories prevent collisions when variants produce the same native filename.
|
|
136
|
+
|
|
137
|
+
Write `dist/packages/<version>/` containing packages, rendered recipes, checksums and a machine-readable build manifest. Record the app/version, selected targets, tool versions, input hashes, configuration digest, output paths/hashes and completed validation. Generate repeatable timestamps from the release or an explicit build epoch. Reject an existing output unless the user explicitly chooses replacement.
|
|
138
|
+
|
|
139
|
+
Publication reads this manifest instead of using the current DEB/RPM filename regex. Check identity, hashes, unique upload names and package ownership before uploading. Preserve upstream binary checksums. An incomplete target set cannot be published as a complete release. Partial CI jobs retain target manifests and the publish job verifies the combined set against the requested configuration.
|
|
140
|
+
|
|
141
|
+
Package generation and publication remain separate commands. AUR, Homebrew and distro submissions use the existing downstream manager. No application Git remotes or submodules are needed. Existing GoReleaser publishers can continue to own their configured destinations.
|
|
142
|
+
|
|
143
|
+
## CI and platforms outside nFPM
|
|
144
|
+
|
|
145
|
+
The reusable workflow installs the configured gem version and packaging tools, then runs the same CLI as a maintainer. Application repositories keep a short workflow call; no Bundler bootstrap is required. Native build jobs supply local artifacts, or the packaging workflow consumes an existing release. PRs validate configuration; gem CI builds and inspects format fixtures.
|
|
146
|
+
|
|
147
|
+
Support explicit target selection for separate Linux and Windows jobs, followed by one aggregation/publish job. Packaging host capabilities and the operating system of the packaged application are separate concerns. Do not promise every target can be built or tested on every host.
|
|
148
|
+
|
|
149
|
+
For Homebrew, reuse existing formula/cask rendering and tap publication. macOS bundle creation, signing and notarization continue to call application-owned scripts. For Windows installers beyond MSIX and for Flatpak, invoke existing tools with their native definitions when those integrations are added. A shared command can coordinate them, but an nFPM format switch cannot replace those tools or port an application.
|
|
150
|
+
|
|
151
|
+
Keep this implementation to a CLI, a configuration loader, input/build coordination, nFPM invocation and the existing downstream manager. Add shared helpers only where actual consumers repeat work; avoid a plugin framework or a new build language.
|
|
152
|
+
|
|
153
|
+
## Implementation and acceptance
|
|
154
|
+
|
|
155
|
+
1. Add the new configuration loader, `init`, `doctor` and `build`; support local inputs and optional release acquisition. Keep legacy commands/configuration readable.
|
|
156
|
+
2. Generalize targets, output manifests, upload validation and nFPM dispatch for all seven formats. Add native configuration examples and fixtures for each.
|
|
157
|
+
3. Test the built gem in an isolated install directory, outside this checkout, without Bundler or a project Gemfile. Verify `init` works in an empty directory and local `build` works without a published release or GitHub credentials.
|
|
158
|
+
4. Exercise package contents and metadata for every format. Test install/remove/upgrade with native package managers in disposable environments, and rebuild an SRPM. Use Windows acceptance tests for MSIX. Track format generation and native installation coverage separately; neither a renamed archive nor an untested binary counts as platform support.
|
|
159
|
+
5. Publish the new gem and matching reusable workflow. Provide `native-packages migrate --dry-run`, then an explicit migration that preserves native recipes and platform exceptions. Remove application wrappers and packaging-only Gemfiles after equivalent outputs are verified. Keep existing Git pins working during transition.
|
|
160
|
+
|
|
161
|
+
The proposed decisions are: one YAML file by default, an installable gem, optional Bundler, package-oriented `init`/`build`/`publish`, all nFPM formats exposed with declared targets, and existing native tools for the remaining platforms. The exact field names and release number can change during review; none of these commands are a promise about v0.1.0.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Configuration reference
|
|
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.
|
|
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
|
+
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.
|
|
23
|
+
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
`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.
|
|
27
|
+
|
|
28
|
+
`before_build` is an argument array, for example:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
before_build: [./scripts/build-linux.sh, '@ARCH@']
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
`after_package` is an optional argument array invoked once per generated package, before output hashes are recorded. 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.
|
|
37
|
+
|
|
38
|
+
## Tokens and additional assets
|
|
39
|
+
|
|
40
|
+
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@`.
|
|
41
|
+
|
|
42
|
+
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.
|
|
43
|
+
|
|
44
|
+
Omitting `--version` requires an exact stable release tag at HEAD. `--release` supplies the version and conflicts with a different `--version`. Stable versions currently use `vMAJOR.MINOR.PATCH`; prerelease tags are rejected. 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.
|
|
45
|
+
|
|
46
|
+
## Output and publication
|
|
47
|
+
|
|
48
|
+
`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.
|
|
49
|
+
|
|
50
|
+
`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`.
|
|
51
|
+
|
|
52
|
+
For builds split across CI jobs:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
native-packages build --version 1.2.3 --target linux-amd64 --output dist/linux
|
|
56
|
+
native-packages build --version 1.2.3 --target windows-amd64 --output dist/windows
|
|
57
|
+
native-packages aggregate dist/linux dist/windows --output dist/complete
|
|
58
|
+
native-packages publish --from dist/complete --to github
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
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.
|
data/docs/legacy.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Legacy v0.1 configuration and commands
|
|
2
|
+
|
|
3
|
+
Package existing Linux release binaries with [nFPM](https://nfpm.goreleaser.com/), generate native distribution recipes, and prepare updates in downstream repositories.
|
|
4
|
+
|
|
5
|
+
Applications keep their own configuration and templates. This repository holds the common Ruby code, tests and reusable GitHub Actions workflow. There are no runtime gem dependencies and no copied engine files in application repositories.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
| Layer | Responsibility |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| Application build jobs | Compile for each OS and architecture; create compatible binaries, macOS bundles and Windows installers; sign and notarize where required. |
|
|
12
|
+
| nFPM | Turn a set of built files and package metadata into native package files. |
|
|
13
|
+
| native-packages | Verify release checksums, render recipes, check Linux ELF dependencies, invoke nFPM, attach packaging assets, and stage or publish downstream updates. |
|
|
14
|
+
| Distribution infrastructure | Build and review submitted recipes, host package indexes, and make packages available to users. |
|
|
15
|
+
|
|
16
|
+
**Version 0.1 creates DEB and RPM files for Linux amd64 and arm64.** nFPM itself also supports Arch Linux, Alpine APK, IPK and MSIX, but those output paths are not wired into this release of the shared CLI. An APK needs suitable binaries, usually built against musl; converting a glibc binary into another package format does not make it compatible. [nFPM configuration](https://nfpm.goreleaser.com/docs/configuration/)
|
|
17
|
+
|
|
18
|
+
Native AUR, Homebrew, Nix, Gentoo, Alpine, Void and other recipes can be supplied as templates. AUR uses `PKGBUILD` and `.SRCINFO`; Homebrew uses formulae or casks. These are distinct from downloadable binary package files. [AUR](https://wiki.archlinux.org/title/Arch_User_Repository), [Homebrew](https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap)
|
|
19
|
+
|
|
20
|
+
Flatpak needs its own runtime, SDK, modules and sandbox permissions. macOS needs application-specific bundle contents and signing settings. Windows needs an appropriate installer and publishing manifest. Keep those native definitions with the app and use their existing tools. This project does not port applications, replace those tools, or claim every application supports every platform. See [platform coverage](platforms.md).
|
|
21
|
+
|
|
22
|
+
## Add an application
|
|
23
|
+
|
|
24
|
+
Use the files in [examples](../examples/packaging/project.yml) as a starting point:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
packaging/
|
|
28
|
+
Gemfile # shared tool dependency
|
|
29
|
+
Gemfile.lock # exact dependency revision
|
|
30
|
+
project.yml # release assets and template mappings
|
|
31
|
+
nfpm.yml # nFPM file mappings and target dependencies
|
|
32
|
+
repositories.yml # registry of downstream destinations
|
|
33
|
+
arch/.../PKGBUILD.in # only the native recipes this app needs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Add `packaging/Gemfile`:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
source "https://rubygems.org"
|
|
40
|
+
gem "native-packages", git: "https://github.com/crmne/native-packages.git", tag: "v0.1.0"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
From the application root:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
export BUNDLE_GEMFILE="$PWD/packaging/Gemfile"
|
|
47
|
+
bundle install
|
|
48
|
+
bundle exec native-packages validate
|
|
49
|
+
bundle exec native-packages prepare 1.2.3
|
|
50
|
+
bundle exec native-packages artifacts dist/packaging/1.2.3
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Commit the Gemfile and lockfile. Bundler records the exact Git revision. No RubyGems publication is required. Run `bundle update native-packages` after changing the selected tool version.
|
|
54
|
+
|
|
55
|
+
Requirements: Ruby 3.2 or later (CI tests 3.4 and 4.0), Bundler, Git, curl, GNU tar, xz, bsdtar, readelf, and nFPM 2.47.0. AUR metadata generation additionally needs `makepkg` or accessible Docker. Publishing needs the destination credentials and GitHub CLI where applicable. Packaging currently runs on Linux; native macOS and Windows builds stay in their own jobs.
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
`project.yml` declares the name, source repository, optional separate `release_repository`, release assets, templates and Linux binary packaging configuration. Stable tags use `vMAJOR.MINOR.PATCH`. `checksums.txt` must contain SHA256 entries for every binary asset. Source archives not present in that list can explicitly use `checksummed: false`; their computed hashes still enter generated recipes.
|
|
60
|
+
|
|
61
|
+
Template values use `@VERSION@`, `@TAG@`, `@NAME@`, `@UPSTREAM@`, `@DATE@`, `@SOURCE_DATE_EPOCH@`, `@GIT_VERSION@`, and per-asset `@KEY_FILE@`, `@KEY_URL@`, `@KEY_SHA256@`. nFPM templates additionally receive `@ROOT@`, `@PAYLOAD@`, `@ARCH@` and `@TARGET@`. Values in `nfpm.yml` otherwise use nFPM's own schema. `binary.nfpm` may reference this file or contain the configuration directly.
|
|
62
|
+
|
|
63
|
+
Include `repositories.yml` even when no downstream publication is needed; use `version: 1` and `repositories: {}` for an empty registry.
|
|
64
|
+
|
|
65
|
+
Files, icons, desktop entries, services, runtime dependencies and platform exceptions remain explicit. ELF inspection checks architecture and raises a glibc dependency floor when needed. It cannot discover every library loaded dynamically or prove compatibility with every distro. Additional shared-library mappings can be supplied under `binary.libraries`; verify dependency names against the target distributions.
|
|
66
|
+
|
|
67
|
+
Optional `version_file` and `version_section` fields check the package or workspace version in a Cargo manifest with `check-version TAG`.
|
|
68
|
+
|
|
69
|
+
## GitHub Actions
|
|
70
|
+
|
|
71
|
+
After the application's stable release job has uploaded binaries and `checksums.txt`, call:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
packaging:
|
|
75
|
+
needs: release
|
|
76
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-')
|
|
77
|
+
permissions:
|
|
78
|
+
contents: write
|
|
79
|
+
uses: crmne/native-packages/.github/workflows/package.yml@v0.1.0
|
|
80
|
+
with:
|
|
81
|
+
version: ${{ github.ref_name }}
|
|
82
|
+
publish: true
|
|
83
|
+
secrets: inherit
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use the same tool release as the Gemfile. Pin the workflow to the corresponding commit SHA for an immutable reference. A separate PR job can call the workflow with `publish: false` and no version; it validates local recipes without requiring an existing release. The shared library's tests run in this repository's CI.
|
|
87
|
+
|
|
88
|
+
With a version supplied, the workflow verifies inputs, builds DEB/RPM files and a recipe archive, and uploads GitHub Actions artifacts. With `publish: true`, it also attaches those package assets and `packaging-checksums.txt` to the existing release. It preserves the original release `checksums.txt`.
|
|
89
|
+
|
|
90
|
+
Optional downstream publication:
|
|
91
|
+
|
|
92
|
+
- AUR: set `PUBLISH_AUR=true`, `AUR_SSH_KEY` and `AUR_KNOWN_HOSTS`; configure an `aur` group in the registry.
|
|
93
|
+
- Homebrew: set `PUBLISH_HOMEBREW=true` and `HOMEBREW_TAP_GITHUB_TOKEN`; configure the `homebrew` destination.
|
|
94
|
+
|
|
95
|
+
Publication is disabled unless requested. Test builds and recipes before enabling a destination. Credentials remain in the application repository's secrets. Workflow failure can be retried without intentionally creating duplicate submissions.
|
|
96
|
+
|
|
97
|
+
If an application already uses GoReleaser's [AUR](https://goreleaser.com/customization/publish/aur/) or [Homebrew](https://goreleaser.com/customization/publish/homebrew_casks/) publisher, continue using it for that destination. Do not configure both publishers for the same package. Use the repository helper for destinations and native recipes those integrations do not cover.
|
|
98
|
+
|
|
99
|
+
## Downstream repositories
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
bundle exec native-packages repositories
|
|
103
|
+
bundle exec native-packages stage aur dist/packaging/1.2.3
|
|
104
|
+
bundle exec native-packages diff aur
|
|
105
|
+
bundle exec native-packages publish aur
|
|
106
|
+
bundle exec native-packages status --json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Each destination has its own ignored clone under `.cache/packaging/repos`. The source repository needs neither submodules nor additional Git remotes. Mapping exact package paths preserves downstream history and unrelated files.
|
|
110
|
+
|
|
111
|
+
The registry supports direct Git pushes, GitHub pull requests, GitLab merge requests and manual destinations. Fork-based submissions require the appropriate fork and a reviewed description passed as `publish TARGET --body-file FILE`. Staging can reuse an existing open request. Dirty changes outside the prepared files, unexpected remote advances and downgrades are rejected. Gentoo updates preserve older ebuilds and Manifest entries. See the [registry example](../examples/packaging/repositories.yml).
|
|
112
|
+
|
|
113
|
+
Upstream review and acceptance are separate from successful submission. This tool does not host APT/DNF repositories or configure signing keys for you.
|
|
114
|
+
|
|
115
|
+
## Development
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
bundle install
|
|
119
|
+
bundle exec ruby -Ilib -e 'Dir["test/*_test.rb"].sort.each { |path| require_relative path }'
|
|
120
|
+
gem build native-packages.gemspec
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Tests use temporary directories and local Git repositories. With nFPM, a C compiler, readelf and bsdtar available, the integration test creates real DEB/RPM packages and verifies their payloads. It does not install them on the host or publish anything externally.
|
data/docs/platforms.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Platform and distribution coverage
|
|
2
|
+
|
|
3
|
+
All seven nFPM 2.47.0 packagers are exposed by the v0.2 CLI. Each target explicitly declares suitable inputs; enabling an output format does not port an application or guarantee acceptance by a distribution.
|
|
4
|
+
|
|
5
|
+
| Output/destination | Shared implementation | Application responsibility |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| DEB | nFPM, ELF inspection, known dependency inference, release upload | Supported distro baseline, runtime-loaded libraries, services/assets and installation testing |
|
|
8
|
+
| RPM | Same, with RPM dependency names | Distribution-specific dependencies and compatibility |
|
|
9
|
+
| Arch package | nFPM `archlinux`, native filename, ELF inspection | Arch-compatible files and explicit dependencies |
|
|
10
|
+
| Alpine APK | nFPM `apk`, ELF/libc checks | Suitable musl/static inputs and Alpine dependencies |
|
|
11
|
+
| IPK | nFPM `ipk`, ELF checks, explicit ABI label | Device/distribution ABI, architecture and dependencies |
|
|
12
|
+
| MSIX | nFPM `msix`, PE architecture checks, `after_package` hook for native signing | Windows executables/DLLs, application identity, assets, capabilities and signing certificate |
|
|
13
|
+
| SRPM | nFPM `srpm`, source/spec input validation | A correct spec and sources, native rebuild testing |
|
|
14
|
+
| AUR | Template rendering, `.SRCINFO`, staged Git publication | Native PKGBUILD source/bin/git variants and build checks |
|
|
15
|
+
| Homebrew | Hash/render supplied formulae or casks and publish a tap | macOS bundles, signing/notarization, native recipe logic |
|
|
16
|
+
| Nixpkgs/Gentoo/Void and similar repositories | Template rendering and configured Git/PR/MR publication | Native recipes, dependency hashes, distro checks and review |
|
|
17
|
+
| Flatpak | No build/publication adapter yet | Use flatpak-builder and native manifests/runtime/sandbox settings |
|
|
18
|
+
| Other Windows installers | No installer adapter beyond MSIX | Existing Inno Setup/NSIS/WiX and WinGet/Scoop integrations |
|
|
19
|
+
|
|
20
|
+
The IPK acceptance fixture targets OpenWrt 24.10.8. OpenWrt 25.12 switched to APK, so IPK is not the package format for every OpenWrt release. [OpenWrt 25.12 release notes](https://openwrt.org/releases/25.12/notes-25.12.0)
|
|
21
|
+
|
|
22
|
+
nFPM ends at constructing the package file, including its supported signing operations. It does not compile the application or host package indexes. [nFPM configuration](https://nfpm.goreleaser.com/docs/configuration/)
|
|
23
|
+
|
|
24
|
+
The Windows acceptance test uses Windows SDK SignTool through `after_package`. Windows rejected nFPM 2.47.0's built-in signature with `0x80096010` in the initial acceptance run; do not assume its signing configuration alone produces a Windows-installable result.
|
|
25
|
+
|
|
26
|
+
The CLI uses known ELF machine/class/endianness mappings and PE machine mappings. Unsupported inspection architectures fail explicitly. Data and source targets do not require an executable. The small DEB/RPM dependency table can be extended in configuration; other formats require explicit runtime dependencies. These checks do not detect every dynamically loaded library or establish compatibility with every version of a distribution.
|
|
27
|
+
|
|
28
|
+
CI builds fixtures in every format and defines native Linux install/upgrade/remove checks, an SRPM rebuild and a signed MSIX installation on Windows. A build manifest reports `installation: not-tested` unless such testing was actually performed for that application output. Fixture coverage is separate from app-specific validation.
|
|
29
|
+
|
|
30
|
+
The [acceptance run for v0.2 development](https://github.com/crmne/native-packages/actions/runs/34748247545) passed on Debian trixie, Fedora 41, Arch's base image, Alpine 3.24.0, OpenWrt 24.10.8 and the GitHub Windows runner. Linux binary tests use a small static executable; the SRPM rebuilds its C source, and the Windows package contains a compiled Windows executable. These fixtures test package construction and lifecycle, not the compatibility of every application's GUI or device integrations.
|
|
31
|
+
|
|
32
|
+
Version 0.1 and its pinned workflow retain their DEB/RPM behavior. The new formats are enabled through the v0.2 single-file configuration and `build` command. Existing v0.1 application configurations do not silently gain more output formats.
|
data/docs/releasing.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Releasing the native-packages gem
|
|
2
|
+
|
|
3
|
+
This repository follows RubyLLM's publishing convention: publishing a GitHub release starts gem publication. Branch and tag pushes run checks without publishing a gem.
|
|
4
|
+
|
|
5
|
+
## Authentication
|
|
6
|
+
|
|
7
|
+
Configure the repository secret `RUBYGEMS_AUTH_TOKEN`, using an existing RubyGems token with permission to push `native-packages`. GitHub passes it to RubyGems through `GEM_HOST_API_KEY`. GitHub Packages uses the workflow's built-in GitHub token.
|
|
8
|
+
|
|
9
|
+
Repository secrets are scoped to their repository. RubyLLM's existing secret does not automatically become available here, and GitHub cannot reveal its value for copying. Use the original token from your credential store or a new appropriately scoped token. A pending trusted publisher is not required for this method.
|
|
10
|
+
|
|
11
|
+
The secret can be set interactively without putting it in a shell command or chat:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
gh secret set RUBYGEMS_AUTH_TOKEN --repo crmne/native-packages
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
[RubyGems Trusted Publishing](https://guides.rubygems.org/trusted-publishing/) is an alternative if the project adopts OIDC later; it is not the current release workflow.
|
|
18
|
+
|
|
19
|
+
## Release procedure
|
|
20
|
+
|
|
21
|
+
Update the gemspec, `NativePackages::VERSION`, example/version references and changelog, then update the development lockfile. Run tests and the isolated gem-install check. Commit and push the reviewed change to `main` and prepare release notes in a file.
|
|
22
|
+
|
|
23
|
+
Create a GitHub release for that commit:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
gh release create v0.2.0 --target main --title 'native-packages 0.2.0' --notes-file release-notes.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Adding `--draft` permits review before publication and does not trigger the publisher. The tag must match the exact gem version and point to a commit on `main`. Set `--prerelease` only for a prerelease gem version.
|
|
30
|
+
|
|
31
|
+
The release workflow verifies the tag, tested commit and prerelease setting, then runs the test workflow, including native package acceptance. It downloads the tested gem from the Ruby 4.0 job, publishes it to RubyGems and GitHub Packages, and attaches it to the GitHub release. It does not rebuild a different artifact after the tests.
|
|
32
|
+
|
|
33
|
+
If authentication is missing, leave the tested gem and release draft available until the secret is configured. Failed release jobs can be rerun after configuration; already-published gem versions are not overwritten. Never move an existing release tag to retry publication.
|