ci: publish the .deb and the .rpm to the forge

3878294 · Gabriel Morell · 2026-09-14 04:16

3 files +106 -0
Message
{commit_body(@commit)}

Files changed

modified .github/workflows/rust-ci.yml
+106 −0
@@ -84,12 +84,118 @@ jobs:
84 84 - name: Install cargo-generate-rpm
85 85 run: cargo install cargo-generate-rpm
86 86
87 + # Every CI build has to carry a distinct version, or the second
88 + # one publishes the same filename with different bytes and the
89 + # registry correctly refuses it with a 409 — and no machine that
90 + # installed the first ever sees the second.
91 + #
92 + # `+` rather than `-`: RPM forbids `-` in a version outright, and
93 + # in both ecosystems `0.1.2+dev.<stamp>` sorts *after* 0.1.2,
94 + # which is what you want from a repository you added in order to
95 + # run the latest build. A tag publishes the bare Cargo version.
96 + #
97 + # One stamp for the whole job, so the .deb and the .rpm from a
98 + # single run agree about what they are.
99 + - name: Stamp the package version
100 + id: version
101 + run: |
102 + set -euo pipefail
103 + base=$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)
104 +
105 + if [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
106 + version="$base"
107 + else
108 + version="$base+dev.$(date -u +%s)"
109 + fi
110 +
111 + echo "version: $version"
112 + echo "version=$version" >> "$GITHUB_OUTPUT"
113 +
114 + # Rewritten after the release build, so the binary is cached
115 + # on the unstamped manifest and only the packaging sees this.
116 + sed -i "0,/^version = .*/s//version = \"$version\"/" Cargo.toml
117 +
87 118 - name: Build test Debian package
88 119 run: cargo deb --no-build --no-strip
89 120
90 121 - name: Build RPM package
91 122 run: cargo generate-rpm
92 123
124 + # `vars.CI_FORGE_URL` is what the forge injects into a run; fall
125 + # back to what the runner already knows, and say so plainly if
126 + # neither resolves rather than handing curl an empty URL.
127 + - name: Resolve the forge URL
128 + env:
129 + CI_FORGE_URL: ${{ vars.CI_FORGE_URL }}
130 + run: |
131 + set -euo pipefail
132 + forge_url=${CI_FORGE_URL:-${GITHUB_SERVER_URL:-}}
133 +
134 + if [ -z "$forge_url" ]; then
135 + echo "No forge URL available." >&2
136 + echo "Set a CI_FORGE_URL variable on this repository or its org." >&2
137 + exit 1
138 + fi
139 +
140 + echo "FORGE_URL=$forge_url" >> "$GITHUB_ENV"
141 +
142 + # `${{ github.token }}` is minted for this job and authorized to
143 + # publish to THIS repository's packages and nowhere else, so
144 + # there is no secret to create first.
145 + #
146 + # Pull requests don't publish: a PR build is a check, and a
147 + # registry that carries every proposed change is not a registry
148 + # anyone can install from.
149 + - name: Publish the .deb and the .rpm to the forge
150 + if: github.event_name != 'pull_request'
151 + env:
152 + REPOSITORY: ${{ github.repository }}
153 + TOKEN: ${{ github.token }}
154 + run: |
155 + set -euo pipefail
156 +
157 + for deb in target/debian/*.deb; do
158 + echo "publishing $deb"
159 + curl --fail-with-body -sS \
160 + -u "gitgud-actions:$TOKEN" \
161 + -H "Content-Type: application/vnd.debian.binary-package" \
162 + --data-binary "@$deb" \
163 + "$FORGE_URL/pkg/deb/$REPOSITORY/upload?dist=stable&component=main"
164 + echo
165 + done
166 +
167 + for rpm in target/generate-rpm/*.rpm; do
168 + echo "publishing $rpm"
169 + curl --fail-with-body -sS \
170 + -u "gitgud-actions:$TOKEN" \
171 + -H "Content-Type: application/x-rpm" \
172 + --data-binary "@$rpm" \
173 + "$FORGE_URL/pkg/rpm/$REPOSITORY/upload"
174 + echo
175 + done
176 +
177 + - name: How to install it
178 + if: github.event_name != 'pull_request'
179 + env:
180 + REPOSITORY: ${{ github.repository }}
181 + OWNER: ${{ github.repository_owner }}
182 + run: |
183 + cat <<EOF
184 + # Debian / Ubuntu
185 + curl -fsSL $FORGE_URL/pkg/_keys/deb/$OWNER | sudo tee /etc/apt/keyrings/$OWNER.asc >/dev/null
186 + echo "deb [signed-by=/etc/apt/keyrings/$OWNER.asc] $FORGE_URL/pkg/deb/$OWNER/_all stable main" | sudo tee /etc/apt/sources.list.d/$OWNER.list
187 + sudo apt update && sudo apt install koco
188 +
189 + # Fedora / RHEL / openSUSE — /etc/yum.repos.d/$OWNER.repo
190 + [$OWNER]
191 + name=$OWNER
192 + baseurl=$FORGE_URL/pkg/rpm/$OWNER/_all
193 + enabled=1
194 + repo_gpgcheck=1
195 + gpgcheck=0
196 + gpgkey=$FORGE_URL/pkg/_keys/rpm/$OWNER
197 + EOF
198 +
93 199 - name: Upload test artifact
94 200 uses: actions/upload-artifact@v4
95 201 with:

Parents: 300ddde