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 +4 -4
- data/CONTRIBUTING.md +86 -0
- data/README.md +52 -121
- data/docs/404.md +12 -0
- data/docs/_guides/apple-notarization.md +116 -0
- data/docs/_guides/building-packages.md +190 -0
- data/docs/_guides/distribution-recipes.md +192 -0
- data/docs/_guides/getting-started.md +184 -0
- data/docs/_guides/github-actions.md +146 -0
- data/docs/_guides/multi-platform.md +153 -0
- data/docs/_guides/native-recipes.md +189 -0
- data/docs/_guides/prereleases.md +72 -0
- data/docs/_guides/publishing.md +143 -0
- data/docs/_guides/release-signing.md +137 -0
- data/docs/_reference/commands.md +206 -0
- data/docs/_reference/configuration.md +323 -0
- data/docs/_reference/platforms.md +104 -0
- data/docs/_reference/troubleshooting.md +172 -0
- data/docs/apple-notarization.md +2 -87
- data/docs/assets/images/logo.svg +27 -0
- data/docs/configuration.md +2 -159
- data/docs/index.md +41 -0
- data/docs/native-recipes.md +3 -134
- data/docs/platforms.md +3 -32
- data/docs/releasing.md +1 -1
- data/examples/native-packages-all-formats.yaml +1 -1
- data/examples/native-packages.yaml +1 -1
- data/lib/native_packages/cli.rb +21 -0
- data/lib/native_packages/release_signing.rb +106 -0
- data/lib/native_packages/support.rb +1 -1
- metadata +22 -3
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Distribution recipes
|
|
3
|
+
description: Generate AUR and Homebrew recipes with release checksums, review downstream changes, and publish repository updates.
|
|
4
|
+
nav_order: 7
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Distribution recipes
|
|
8
|
+
|
|
9
|
+
A distribution recipe tells a package manager where to get your app and how
|
|
10
|
+
to install or build it. Examples include an AUR `PKGBUILD`, a Homebrew formula
|
|
11
|
+
or cask, and a Gentoo ebuild.
|
|
12
|
+
|
|
13
|
+
native-packages fills in versions, download URLs, and checksums in templates
|
|
14
|
+
you keep with the app. It can then stage those files in a downstream Git
|
|
15
|
+
repository for review and publication.
|
|
16
|
+
|
|
17
|
+
This guide uses an AUR package as an example. The same asset and template
|
|
18
|
+
settings work for other recipe formats.
|
|
19
|
+
|
|
20
|
+
## 1. Declare the release asset
|
|
21
|
+
|
|
22
|
+
Add an asset for the archive your recipe downloads:
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
release:
|
|
26
|
+
repository: your-name/hello
|
|
27
|
+
assets:
|
|
28
|
+
AMD64:
|
|
29
|
+
file: hello_@VERSION@_linux_amd64.tar.gz
|
|
30
|
+
local: dist/hello_@VERSION@_linux_amd64.tar.gz
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For local builds, native-packages hashes `local`. In release mode, it downloads
|
|
34
|
+
`file` from the configured release and verifies its entry in `checksums.txt`.
|
|
35
|
+
An explicit `url` can point elsewhere.
|
|
36
|
+
|
|
37
|
+
Each asset provides three values for templates: `@AMD64_FILE@`,
|
|
38
|
+
`@AMD64_URL@`, and `@AMD64_SHA256@`. Use uppercase names such as `AMD64`
|
|
39
|
+
or `MACOS` for asset keys.
|
|
40
|
+
|
|
41
|
+
## 2. Write a template
|
|
42
|
+
|
|
43
|
+
Create `packaging/arch/hello-bin/PKGBUILD.in`:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
pkgname=hello-bin
|
|
47
|
+
pkgver=@VERSION@
|
|
48
|
+
pkgrel=@PKGREL@
|
|
49
|
+
pkgdesc='A small greeting application'
|
|
50
|
+
arch=('x86_64')
|
|
51
|
+
url='@UPSTREAM@'
|
|
52
|
+
license=('MIT')
|
|
53
|
+
depends=('glibc')
|
|
54
|
+
provides=('hello')
|
|
55
|
+
conflicts=('hello')
|
|
56
|
+
source=('@AMD64_URL@')
|
|
57
|
+
sha256sums=('@AMD64_SHA256@')
|
|
58
|
+
|
|
59
|
+
package() {
|
|
60
|
+
install -Dm755 hello "$pkgdir/usr/bin/hello"
|
|
61
|
+
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/hello/LICENSE"
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This example expects the archive to contain `hello` and `LICENSE` at its root.
|
|
66
|
+
Use dependencies and metadata appropriate to your actual app.
|
|
67
|
+
|
|
68
|
+
Map the generated path to the template in `native-packages.yaml`:
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
templates:
|
|
72
|
+
arch/hello-bin/PKGBUILD: packaging/arch/hello-bin/PKGBUILD.in
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The left side is a path under the build's `recipes/` directory. The right side
|
|
76
|
+
is a source path relative to your configuration.
|
|
77
|
+
|
|
78
|
+
For paths matching `arch/<package>/PKGBUILD`, native-packages also generates
|
|
79
|
+
`.SRCINFO`, the package metadata used by AUR. This needs `makepkg` or working
|
|
80
|
+
Docker. Recipe archives need `tar` and `xz`.
|
|
81
|
+
|
|
82
|
+
## 3. Generate and test the recipe
|
|
83
|
+
|
|
84
|
+
Build with your existing package targets and the new settings:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
native-packages build --version 1.2.3 --output dist/with-recipes
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Look in `dist/with-recipes/recipes/arch/hello-bin/` for `PKGBUILD` and `.SRCINFO`.
|
|
91
|
+
Review the rendered URLs, version, checksum, dependencies, and installation
|
|
92
|
+
paths. Test the recipe with the destination's normal tooling on a suitable
|
|
93
|
+
machine before publishing it.
|
|
94
|
+
|
|
95
|
+
A project that only generates recipes can use `targets: {}`. It still needs
|
|
96
|
+
`schema`, `tool`, `nfpm.name`, and the asset/template configuration.
|
|
97
|
+
|
|
98
|
+
## 4. Configure a destination
|
|
99
|
+
|
|
100
|
+
Add the existing downstream repository under `repositories`:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
repositories:
|
|
104
|
+
aur-bin:
|
|
105
|
+
group: aur
|
|
106
|
+
url: https://aur.archlinux.org/hello-bin.git
|
|
107
|
+
push_url: ssh://aur@aur.archlinux.org/hello-bin.git
|
|
108
|
+
branch: master
|
|
109
|
+
package_path: .
|
|
110
|
+
files:
|
|
111
|
+
arch/hello-bin/PKGBUILD: PKGBUILD
|
|
112
|
+
arch/hello-bin/.SRCINFO: .SRCINFO
|
|
113
|
+
version_file: PKGBUILD
|
|
114
|
+
version_pattern: '^pkgver=(\S+)'
|
|
115
|
+
publish: push
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Use your actual package repository and configure credentials for it. `files`
|
|
119
|
+
maps generated paths under `recipes/` to paths in the downstream repository.
|
|
120
|
+
`version_pattern` extracts the existing version so the tool can detect updates
|
|
121
|
+
and downgrades.
|
|
122
|
+
|
|
123
|
+
The `group` lets you operate on related destinations together. For example,
|
|
124
|
+
`aur` can select both a binary package and a source package.
|
|
125
|
+
|
|
126
|
+
## 5. Stage, review, and publish
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
native-packages repositories
|
|
130
|
+
native-packages stage aur dist/with-recipes/recipes
|
|
131
|
+
native-packages diff aur
|
|
132
|
+
native-packages publish aur
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`stage` prepares the update in an independent checkout under
|
|
136
|
+
`.cache/packaging/repos/`. `diff` shows what will change. `publish` commits and
|
|
137
|
+
pushes the staged update. Add `.cache/` to your application's `.gitignore`.
|
|
138
|
+
|
|
139
|
+
Each destination has its own checkout. Your app needs no Git submodules or
|
|
140
|
+
additional remotes. Updates touch the mapped package paths and preserve other
|
|
141
|
+
files; Gentoo updates also preserve older ebuilds and Manifest entries.
|
|
142
|
+
|
|
143
|
+
Check downstream state with:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
native-packages status
|
|
147
|
+
native-packages status aur --offline --json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The offline form uses cached information. Normal status checks query upstream
|
|
151
|
+
repositories and open requests.
|
|
152
|
+
|
|
153
|
+
## Homebrew formulae and casks
|
|
154
|
+
|
|
155
|
+
Keep a formula or cask template in your app, then map it through `templates`
|
|
156
|
+
and `repositories.files` just like the AUR example. A tap you own typically
|
|
157
|
+
uses `publish: push` and a destination named `homebrew`.
|
|
158
|
+
|
|
159
|
+
Use a formula for the appropriate command-line package or a cask for a native
|
|
160
|
+
app download. Your template owns the package manager's installation logic.
|
|
161
|
+
If a cask refers to a DMG created by this release, use
|
|
162
|
+
[deferred recipe generation](multi-platform.md#generate-recipes-after-packages-are-built)
|
|
163
|
+
so its checksum comes from the completed, signed image.
|
|
164
|
+
|
|
165
|
+
## Submit a pull request or merge request
|
|
166
|
+
|
|
167
|
+
Use `publish: github-pr` or `publish: gitlab-mr` for a repository that accepts
|
|
168
|
+
contributions through review. Create the fork first and supply its URLs and
|
|
169
|
+
submission settings. The [repository reference](../_reference/configuration.md#repositories)
|
|
170
|
+
lists these fields.
|
|
171
|
+
|
|
172
|
+
Staging writes a starting description to `.cache/packaging/submissions/` and
|
|
173
|
+
prints its path. Edit it to describe the update and the checks you ran, then
|
|
174
|
+
publish that destination by name:
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
native-packages diff community
|
|
178
|
+
native-packages publish community --body-file .cache/packaging/submissions/community.md
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The tool can reuse an existing open request. Successful submission means the
|
|
182
|
+
request exists; the upstream project still reviews and accepts it.
|
|
183
|
+
|
|
184
|
+
Use `publish: manual` with `notes` for destinations that need an external
|
|
185
|
+
process. The CLI reports those instructions rather than submitting an update.
|
|
186
|
+
|
|
187
|
+
## Next steps
|
|
188
|
+
|
|
189
|
+
Once the process is tested, enable destination publication in
|
|
190
|
+
[GitHub Actions](github-actions.md#enable-aur-or-homebrew-publication).
|
|
191
|
+
For package files themselves, use [Publishing a release](publishing.md).
|
|
192
|
+
This tool does not host APT or DNF package indexes.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Getting started
|
|
3
|
+
description: Install native-packages and build a DEB and RPM from a compiled Linux application.
|
|
4
|
+
nav_order: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Getting started
|
|
8
|
+
|
|
9
|
+
By the end of this guide, you will have a DEB and an RPM containing your app,
|
|
10
|
+
ready to test on Linux.
|
|
11
|
+
|
|
12
|
+
We will package an application called `hello`. You can follow along with your
|
|
13
|
+
own compiled executable, or build the tiny example below.
|
|
14
|
+
|
|
15
|
+
## 1. Install the tools
|
|
16
|
+
|
|
17
|
+
You need Ruby 3.2 or later. Install the version used by these guides:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
gem install native-packages --version 0.7.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For Linux packages, install **nFPM 2.47.0**, the helper native-packages uses to
|
|
24
|
+
write package files. Download the matching build from the
|
|
25
|
+
[nFPM release](https://github.com/goreleaser/nfpm/releases/tag/v2.47.0)
|
|
26
|
+
and put `nfpm` on your `PATH`. If you already use Go, you can install it with:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.47.0
|
|
30
|
+
export PATH="$(go env GOPATH)/bin:$PATH"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You also need `readelf` to inspect Linux binaries and `bsdtar` to unpack
|
|
34
|
+
archives. On Debian or Ubuntu:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
sudo apt-get install binutils libarchive-tools
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Other distributions provide these through their binutils and libarchive
|
|
41
|
+
packages. The [reusable GitHub Actions workflow](github-actions.md) installs
|
|
42
|
+
the packaging tools for you.
|
|
43
|
+
|
|
44
|
+
## 2. Prepare your application
|
|
45
|
+
|
|
46
|
+
Start in your application's root directory. This example expects a Linux
|
|
47
|
+
x86-64 executable at `dist/hello`, built against glibc.
|
|
48
|
+
|
|
49
|
+
If you have a C compiler on an x86-64 Linux system using glibc, you can create
|
|
50
|
+
a sample in a new directory:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
mkdir hello-packaging
|
|
54
|
+
cd hello-packaging
|
|
55
|
+
mkdir dist
|
|
56
|
+
cat > hello.c <<'C'
|
|
57
|
+
#include <stdio.h>
|
|
58
|
+
int main(void) {
|
|
59
|
+
puts("Hello from a native package!");
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
C
|
|
63
|
+
cc -o dist/hello hello.c
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For your own app, run its usual build command instead and note where it puts
|
|
67
|
+
the executable. Packaging starts from those built files.
|
|
68
|
+
|
|
69
|
+
## 3. Create a configuration
|
|
70
|
+
|
|
71
|
+
Generate a starting point:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
native-packages init --name hello --formats deb,rpm
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Open the generated `native-packages.yaml` and replace its contents with:
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
schema: 1
|
|
81
|
+
tool:
|
|
82
|
+
version: '0.7.0'
|
|
83
|
+
nfpm: '2.47.0'
|
|
84
|
+
|
|
85
|
+
nfpm:
|
|
86
|
+
name: hello
|
|
87
|
+
description: A small greeting application
|
|
88
|
+
maintainer: Your Name <you@example.com>
|
|
89
|
+
license: MIT
|
|
90
|
+
contents:
|
|
91
|
+
- src: '@PAYLOAD@/hello'
|
|
92
|
+
dst: /usr/bin/hello
|
|
93
|
+
file_info:
|
|
94
|
+
mode: 0755
|
|
95
|
+
|
|
96
|
+
targets:
|
|
97
|
+
linux-amd64:
|
|
98
|
+
platform: linux
|
|
99
|
+
arch: amd64
|
|
100
|
+
libc: glibc
|
|
101
|
+
formats: [deb, rpm]
|
|
102
|
+
input:
|
|
103
|
+
kind: file
|
|
104
|
+
local: dist/hello
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use your own maintainer details and your app's actual license. There are three
|
|
108
|
+
parts to understand:
|
|
109
|
+
|
|
110
|
+
- **`tool`** selects the tool versions, so everyone builds with the same setup.
|
|
111
|
+
- **`nfpm`** describes the package: its name, metadata, and installed files.
|
|
112
|
+
`src` is the file to include; `dst` is where it will be installed.
|
|
113
|
+
- **`targets`** describes the build inputs and output formats. `amd64` means
|
|
114
|
+
x86-64, and `glibc` is the C library used by this example's executable.
|
|
115
|
+
|
|
116
|
+
`@PAYLOAD@` is a temporary copy of your input. Here, it contains `hello`.
|
|
117
|
+
The destination `/usr/bin/hello` is inside the package; building does not
|
|
118
|
+
install it on your machine.
|
|
119
|
+
|
|
120
|
+
The default generated configuration expects an archive. We set `kind: file`
|
|
121
|
+
because this example supplies one executable. For ARM64, use `arch: arm64`
|
|
122
|
+
and an ARM64 build of your app. See [input types and targets](building-packages.md).
|
|
123
|
+
|
|
124
|
+
## 4. Check and build
|
|
125
|
+
|
|
126
|
+
Check the configuration and tools:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
native-packages doctor
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
If anything is missing, the command reports what to fix. Once it succeeds,
|
|
133
|
+
build version 1.2.3:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
native-packages build --version 1.2.3
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The command checks your executable's architecture and linked libraries, then
|
|
140
|
+
creates both packages. You should see:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
dist/packages/1.2.3/
|
|
144
|
+
packages/
|
|
145
|
+
linux-amd64/
|
|
146
|
+
deb/ # your .deb file
|
|
147
|
+
rpm/ # your .rpm file
|
|
148
|
+
recipes/
|
|
149
|
+
release.json
|
|
150
|
+
build.json
|
|
151
|
+
packaging-checksums.txt
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`build.json` records the inputs, outputs, and checks performed.
|
|
155
|
+
`packaging-checksums.txt` lists file hashes so changes can be detected.
|
|
156
|
+
Keep the whole directory if you plan to publish the build later.
|
|
157
|
+
|
|
158
|
+
To try again after changing your app or configuration, choose a new output
|
|
159
|
+
directory:
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
native-packages build --version 1.2.3 --output dist/second-build
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## 5. Test the package
|
|
166
|
+
|
|
167
|
+
On a disposable Debian or Ubuntu machine, copy the DEB there and install it:
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
sudo apt install ./hello_1.2.3_amd64.deb
|
|
171
|
+
hello
|
|
172
|
+
sudo apt remove hello
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Use the filename produced by your build. For the sample, `hello` prints
|
|
176
|
+
`Hello from a native package!`. For your own app, also test startup, upgrades,
|
|
177
|
+
and removal on each distribution you support. A successful package build
|
|
178
|
+
checks the files; installation testing checks how the app behaves.
|
|
179
|
+
|
|
180
|
+
## Where to go next
|
|
181
|
+
|
|
182
|
+
Continue with [Building packages](building-packages.md) to add icons,
|
|
183
|
+
configuration files, dependencies, and more architectures. When your package
|
|
184
|
+
is ready, follow [Publishing a release](publishing.md).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GitHub Actions
|
|
3
|
+
description: Add package building and optional publication to your application's GitHub Actions workflow.
|
|
4
|
+
nav_order: 4
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GitHub Actions
|
|
8
|
+
|
|
9
|
+
The reusable workflow installs the tools, builds your packages, and saves the
|
|
10
|
+
result as an Actions artifact. It can also upload packages to an existing
|
|
11
|
+
GitHub release.
|
|
12
|
+
|
|
13
|
+
Before adding it, commit `native-packages.yaml` and check that you can
|
|
14
|
+
[build locally](getting-started.md).
|
|
15
|
+
|
|
16
|
+
## Package an existing release
|
|
17
|
+
|
|
18
|
+
Add this job under `jobs` in your application's release workflow. In this
|
|
19
|
+
example, the existing `release` job uploads the application's binary archives
|
|
20
|
+
and `checksums.txt` to a release matching the Git tag.
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
packaging:
|
|
24
|
+
needs: release
|
|
25
|
+
permissions:
|
|
26
|
+
contents: write
|
|
27
|
+
uses: crmne/native-packages/.github/workflows/package.yml@v0.7.0
|
|
28
|
+
with:
|
|
29
|
+
version: ${{ github.ref_name }}
|
|
30
|
+
publish: true
|
|
31
|
+
secrets: inherit
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Set `needs` to your actual release job's name. Use this example in a tag-based
|
|
35
|
+
release workflow, where `github.ref_name` is a version such as `v1.2.3`.
|
|
36
|
+
For other triggers, pass the release version explicitly.
|
|
37
|
+
|
|
38
|
+
The configuration must include `release.repository` and a `release_asset`
|
|
39
|
+
for each selected target. See [Publishing a release](publishing.md).
|
|
40
|
+
|
|
41
|
+
Use the same native-packages release for the workflow and `tool.version`.
|
|
42
|
+
For an immutable workflow reference, replace `v0.7.0` with that release's
|
|
43
|
+
full commit SHA.
|
|
44
|
+
|
|
45
|
+
## Build without publishing
|
|
46
|
+
|
|
47
|
+
Set `publish: false` to build and upload the `native-packages` Actions
|
|
48
|
+
artifact without attaching anything to the GitHub release. This is useful
|
|
49
|
+
while you test the workflow.
|
|
50
|
+
|
|
51
|
+
With no `version`, the reusable workflow only validates the configuration:
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
name: Check packaging
|
|
55
|
+
on: [pull_request]
|
|
56
|
+
permissions:
|
|
57
|
+
contents: read
|
|
58
|
+
jobs:
|
|
59
|
+
packaging:
|
|
60
|
+
uses: crmne/native-packages/.github/workflows/package.yml@v0.7.0
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Validation does not compile the app or check that future release inputs exist.
|
|
64
|
+
|
|
65
|
+
## Use files from an Actions artifact
|
|
66
|
+
|
|
67
|
+
If a preceding job uploads your compiled app as an Actions artifact, use
|
|
68
|
+
`source-artifact` instead of downloading inputs from a GitHub release:
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
packaging:
|
|
72
|
+
needs: build
|
|
73
|
+
permissions:
|
|
74
|
+
contents: write
|
|
75
|
+
uses: crmne/native-packages/.github/workflows/package.yml@v0.7.0
|
|
76
|
+
with:
|
|
77
|
+
version: '1.2.3'
|
|
78
|
+
source-artifact: linux-binaries
|
|
79
|
+
source-directory: dist
|
|
80
|
+
publish: false
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Here, the existing `build` job must upload an artifact named `linux-binaries`.
|
|
84
|
+
The workflow extracts it under `dist`. Its filenames and directory structure
|
|
85
|
+
must match your targets' `input.local` paths. This uses local build mode,
|
|
86
|
+
which runs any configured `before_build` hook.
|
|
87
|
+
|
|
88
|
+
## Select Linux targets in a shared configuration
|
|
89
|
+
|
|
90
|
+
The reusable workflow runs on Linux. If your configuration also has DMG or
|
|
91
|
+
Inno targets, select the Linux targets explicitly:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
with:
|
|
95
|
+
version: ${{ github.ref_name }}
|
|
96
|
+
targets: linux-amd64,linux-arm64
|
|
97
|
+
publish: true
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The workflow passes the same target selection to build and publication.
|
|
101
|
+
It requires every format declared for those targets. An empty selection
|
|
102
|
+
means all configured targets.
|
|
103
|
+
|
|
104
|
+
Build DMG and Inno targets in your own macOS and Windows jobs with the CLI.
|
|
105
|
+
See [Building across platforms](multi-platform.md) for combining their outputs
|
|
106
|
+
and generating recipes after all packages are available.
|
|
107
|
+
|
|
108
|
+
## Workflow inputs
|
|
109
|
+
|
|
110
|
+
| Input | Default | Purpose |
|
|
111
|
+
| --- | --- | --- |
|
|
112
|
+
| `version` | Empty | App version or tag. Empty means validate only. |
|
|
113
|
+
| `publish` | `false` | Upload packages to the existing release; enable configured downstream publishing. |
|
|
114
|
+
| `targets` | Empty | Comma-separated target IDs. Empty selects all targets. |
|
|
115
|
+
| `config` | Auto-discovered | Path to the configuration file. |
|
|
116
|
+
| `source-artifact` | Empty | Artifact containing local inputs. Empty uses GitHub release assets. |
|
|
117
|
+
| `source-directory` | `dist` | Where to download that artifact, relative to the checkout. |
|
|
118
|
+
|
|
119
|
+
## Enable AUR or Homebrew publication
|
|
120
|
+
|
|
121
|
+
First set up and test the [downstream destination](distribution-recipes.md).
|
|
122
|
+
Then configure these repository variables and secrets in your application's
|
|
123
|
+
GitHub repository:
|
|
124
|
+
|
|
125
|
+
| Destination | Repository variable | Secrets |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| AUR group `aur` | `PUBLISH_AUR=true` | `AUR_SSH_KEY`, `AUR_KNOWN_HOSTS` |
|
|
128
|
+
| Destination or group `homebrew` | `PUBLISH_HOMEBREW=true` | `HOMEBREW_TAP_GITHUB_TOKEN` |
|
|
129
|
+
|
|
130
|
+
These steps run only with `publish: true`. The Homebrew token needs write
|
|
131
|
+
access to your tap; the AUR key needs access to the configured repositories.
|
|
132
|
+
Use `secrets: inherit` as in the release example, or pass the named secrets
|
|
133
|
+
explicitly. If another tool already publishes a destination, keep one
|
|
134
|
+
publisher responsible for it.
|
|
135
|
+
|
|
136
|
+
## Multiple jobs and configurations
|
|
137
|
+
|
|
138
|
+
The reusable workflow gives different configuration paths and target
|
|
139
|
+
selections separate concurrency groups. If you are still using the old
|
|
140
|
+
`v0.5.0` workflow, serialize calls with `needs` or upgrade to avoid calls
|
|
141
|
+
interfering with one another.
|
|
142
|
+
|
|
143
|
+
When downloading build outputs from native jobs, preserve the entire build
|
|
144
|
+
directory, including hidden files in generated recipes. See
|
|
145
|
+
[Building across platforms](multi-platform.md) for the shared timestamp and
|
|
146
|
+
checkout requirements.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Building across platforms
|
|
3
|
+
description: Build targets on their required hosts, combine the results, and generate distribution recipes once all packages are ready.
|
|
4
|
+
nav_order: 8
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Building across platforms
|
|
8
|
+
|
|
9
|
+
When a release includes Linux packages, a DMG, and a Windows installer, each
|
|
10
|
+
build job can produce its own directory. **Aggregation** combines those
|
|
11
|
+
verified directories into one result you can publish.
|
|
12
|
+
|
|
13
|
+
This guide assumes your configuration already declares the targets. Use
|
|
14
|
+
[Building packages](building-packages.md) for Linux and
|
|
15
|
+
[macOS and Windows installers](native-recipes.md) for native targets.
|
|
16
|
+
|
|
17
|
+
## Use the same release inputs
|
|
18
|
+
|
|
19
|
+
Every job must use the same configuration, app version, and build timestamp.
|
|
20
|
+
Check out the same commit with the same Git history depth on every host.
|
|
21
|
+
Set `SOURCE_DATE_EPOCH` to the same Unix timestamp in each job, normally the
|
|
22
|
+
release commit's timestamp.
|
|
23
|
+
|
|
24
|
+
For example, in a shell on Linux or macOS:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
export SOURCE_DATE_EPOCH="$(git show -s --format=%ct HEAD)"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
In PowerShell on Windows:
|
|
31
|
+
|
|
32
|
+
```powershell
|
|
33
|
+
$env:SOURCE_DATE_EPOCH = git show -s --format=%ct HEAD
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
In GitHub Actions, use `fetch-depth: 0` on each checkout so Git-derived recipe
|
|
37
|
+
values agree. Native packaging scripts should respect the shared timestamp
|
|
38
|
+
where their tools support it.
|
|
39
|
+
|
|
40
|
+
## Build each target on its host
|
|
41
|
+
|
|
42
|
+
For a project with exactly these three targets, run the corresponding command
|
|
43
|
+
in each job:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
# Linux
|
|
47
|
+
native-packages build --version 1.2.3 --target linux-amd64 --output dist/linux
|
|
48
|
+
|
|
49
|
+
# macOS
|
|
50
|
+
native-packages build --version 1.2.3 --target macos-arm64 --output dist/macos
|
|
51
|
+
|
|
52
|
+
# Windows
|
|
53
|
+
native-packages build --version 1.2.3 --target windows-amd64 --output dist/windows
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Transfer the complete build directories to the machine that will combine
|
|
57
|
+
and publish them. Keep `build.json`, the package subdirectories, and any
|
|
58
|
+
recipes. Preserve hidden files such as `.SRCINFO` when uploading CI artifacts.
|
|
59
|
+
|
|
60
|
+
Then run from a checkout with the same configuration:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
native-packages aggregate dist/linux dist/macos dist/windows --output dist/complete
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The command checks hashes and rejects overlapping target/format outputs,
|
|
67
|
+
conflicting recipe files, and missing targets. The destination must be new.
|
|
68
|
+
The original build directories are preserved.
|
|
69
|
+
|
|
70
|
+
After your app's package tests pass:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
native-packages publish --from dist/complete --to github
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Generate recipes after packages are built
|
|
77
|
+
|
|
78
|
+
A Homebrew cask may need the checksum of the DMG produced by this very release.
|
|
79
|
+
In that case, **defer recipes**: build the packages first and render recipes
|
|
80
|
+
once the final files are available.
|
|
81
|
+
|
|
82
|
+
On each host, add `--defer-recipes`:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
native-packages doctor --target linux-amd64 --defer-recipes
|
|
86
|
+
native-packages build --version 1.2.3 --target linux-amd64 --defer-recipes --output dist/linux
|
|
87
|
+
native-packages build --version 1.2.3 --target macos-arm64 --defer-recipes --output dist/macos
|
|
88
|
+
native-packages build --version 1.2.3 --target windows-amd64 --defer-recipes --output dist/windows
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Each job still checks its selected targets and runs signing hooks, but skips
|
|
92
|
+
global recipe assets and recipe tools. AUR tooling is therefore needed only
|
|
93
|
+
on the finalization host.
|
|
94
|
+
|
|
95
|
+
Collect the results on Linux, along with any additional recipe assets, and run:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
native-packages aggregate dist/linux dist/macos dist/windows \
|
|
99
|
+
--finalize-recipes --output dist/complete
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The command verifies all targets, resolves asset hashes, generates the recipes
|
|
103
|
+
and recipe archive, and writes a completed build. You can then test and publish:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
native-packages publish --from dist/complete --to github,aur,homebrew
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Only name destinations you have configured. A deferred build cannot be
|
|
110
|
+
published directly, and ordinary and deferred build directories cannot be
|
|
111
|
+
mixed in one aggregate.
|
|
112
|
+
|
|
113
|
+
## Connect a recipe asset to a built package
|
|
114
|
+
|
|
115
|
+
Declare the asset's `file` to match the native package's output filename:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
assets:
|
|
119
|
+
MACOS:
|
|
120
|
+
file: hello-@TAG@-macos-arm64.dmg
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For version 1.2.3, the finalizer finds the verified package named
|
|
124
|
+
`hello-v1.2.3-macos-arm64.dmg`. Its hash includes signing and notarization.
|
|
125
|
+
A recipe can then use `@MACOS_URL@` and `@MACOS_SHA256@`.
|
|
126
|
+
|
|
127
|
+
A matching package takes precedence over an asset's `local` path. Package
|
|
128
|
+
filenames must be unique. Other assets, such as source or portable archives,
|
|
129
|
+
need their configured `local` files on the finalization host. Finalization
|
|
130
|
+
does not download those assets, even when the target builds used `--release`.
|
|
131
|
+
|
|
132
|
+
## Requirements for finalization
|
|
133
|
+
|
|
134
|
+
All input directories must defer recipes and agree on configuration, version,
|
|
135
|
+
timestamp, tool versions, and recipe metadata. Include every configured target
|
|
136
|
+
and format. The finalizer needs `tar` and `xz` for recipe archives, and
|
|
137
|
+
`makepkg` or working Docker for AUR metadata.
|
|
138
|
+
|
|
139
|
+
A deferred target can use asset filenames and URLs, but it cannot use an
|
|
140
|
+
unknown asset hash such as `@MACOS_SHA256@` in its own input, package definition,
|
|
141
|
+
or hooks. Such a target needs an ordinary build with that asset already
|
|
142
|
+
available. Release downloads still require checksums when recipes are deferred.
|
|
143
|
+
|
|
144
|
+
Prerelease recipes cannot be finalized. See [Prereleases](prereleases.md)
|
|
145
|
+
for using a shared native configuration with stable recipes.
|
|
146
|
+
|
|
147
|
+
## Publish Linux targets separately
|
|
148
|
+
|
|
149
|
+
If your app's own jobs already upload the native installers, you can use the
|
|
150
|
+
[reusable Linux workflow](github-actions.md#select-linux-targets-in-a-shared-configuration)
|
|
151
|
+
with `targets: linux-amd64,linux-arm64`. That workflow builds and publishes
|
|
152
|
+
exactly those complete targets. This is useful when you do not need a combined
|
|
153
|
+
release directory or deferred recipe finalization.
|