Skip to content

Commit 070e1d0

Browse files
edavidajaclaude
authored andcommitted
Add RPM support and Cloudsmith publishing for Linux packages
This commit introduces comprehensive RPM package support alongside existing DEB packages, migrates to nfpm for package building, and adds automated Cloudsmith publishing. Package Building Changes: - Migrated from dpkg-deb to nfpm for both DEB and RPM package creation - Added makeInstallerRpm() function in installer.ts using shared nfpm configuration - Created RPM-specific post-install and post-remove scripts in package/scripts/linux/rpm/ - Added js-yaml import for generating nfpm configuration files - Implemented architecture mapping (DEB: amd64/arm64, RPM: x86_64/aarch64) GitHub Actions Workflow Improvements: - Consolidated 4 separate Linux installer jobs into single matrix job (make-installer-linux) - Matrix: arch=[x86_64, aarch64] × format=[deb, rpm] - Reduced workflow from ~160 to ~60 lines for Linux installers - Added nfpm installation step (downloads binary from GitHub releases, version 2.43.1) - Updated all artifact references to use new naming: Linux-{format}-{arch}-Installer Cloudsmith Publishing: - Added cloudsmith-push job for automated package repository publishing - Publishes to both "open" and "pro" Posit repositories - Uses matrix strategy: 2 archs × 2 formats × 2 repos = 8 push operations - Configured with any-distro/any-version for broad compatibility Build System Updates: - Added make-installer-rpm command to bld.ts - Updated all job dependencies (publish-release, cleanup-when-failure, docker-push) - Updated checksum generation and release file paths for new artifact names This enables users to install Quarto via standard package managers (apt, yum, dnf, zypper) from Posit's Cloudsmith repositories after configuring the appropriate repository source. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 22ecd3c commit 070e1d0

File tree

5 files changed

+306
-137
lines changed

5 files changed

+306
-137
lines changed

.github/workflows/create-release.yml

Lines changed: 104 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ on:
1515
type: boolean
1616
default: true
1717

18+
env:
19+
NFPM_VERSION: "2.43.1"
20+
1821
concurrency:
1922
# make publishing release concurrent (but others trigger not)
2023
group: building-releases-${{ inputs.publish-release && 'prerelease' || github.run_id }}
@@ -242,9 +245,13 @@ jobs:
242245
name: RHEL Zip
243246
path: ./package/quarto-${{needs.configure.outputs.version}}-linux-rhel7-amd64.tar.gz
244247

245-
make-installer-arm64-deb:
248+
make-installer-linux:
246249
runs-on: ubuntu-latest
247250
needs: [configure]
251+
strategy:
252+
matrix:
253+
arch: [x86_64, aarch64]
254+
format: [deb, rpm]
248255
steps:
249256
- uses: actions/checkout@v4
250257
with:
@@ -258,57 +265,47 @@ jobs:
258265
run: |
259266
./configure.sh
260267
261-
- name: Prepare Distribution
262-
run: |
263-
pushd package/src/
264-
./quarto-bld prepare-dist --set-version ${{needs.configure.outputs.version}} --arch aarch64 --log-level info
265-
popd
266-
267-
- name: Make Installer
268-
run: |
269-
pushd package/src/
270-
./quarto-bld make-installer-deb --set-version ${{needs.configure.outputs.version}} --arch aarch64 --log-level info
271-
popd
272-
273-
- name: Upload Artifact
274-
uses: actions/upload-artifact@v4
275-
with:
276-
name: Deb Arm64 Installer
277-
path: ./package/out/quarto-${{needs.configure.outputs.version}}-linux-arm64.deb
278-
279-
make-installer-deb:
280-
runs-on: ubuntu-latest
281-
needs: [configure]
282-
steps:
283-
- uses: actions/checkout@v4
284-
with:
285-
ref: ${{ needs.configure.outputs.version_commit }}
286-
287-
- name: Prevent Re-run
288-
if: ${{ inputs.publish-release }}
289-
uses: ./.github/workflows/actions/prevent-rerun
290-
291-
- name: Configure
268+
- name: Install nfpm
292269
run: |
293-
./configure.sh
270+
wget -q https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_Linux_x86_64.tar.gz
271+
tar -xzf nfpm_${NFPM_VERSION}_Linux_x86_64.tar.gz
272+
sudo mv nfpm /usr/local/bin/
273+
nfpm --version
294274
295275
- name: Prepare Distribution
296276
run: |
297277
pushd package/src/
298-
./quarto-bld prepare-dist --set-version ${{needs.configure.outputs.version}} --log-level info
278+
./quarto-bld prepare-dist --set-version ${{needs.configure.outputs.version}} ${{ matrix.arch == 'aarch64' && '--arch aarch64' || '' }} --log-level info
299279
popd
300280
301281
- name: Make Installer
302282
run: |
303283
pushd package/src/
304-
./quarto-bld make-installer-deb --set-version ${{needs.configure.outputs.version}} --log-level info
284+
./quarto-bld make-installer-${{ matrix.format }} --set-version ${{needs.configure.outputs.version}} ${{ matrix.arch == 'aarch64' && '--arch aarch64' || '' }} --log-level info
305285
popd
306286
287+
- name: Set package architecture name
288+
id: pkg_arch
289+
run: |
290+
if [ "${{ matrix.format }}" == "deb" ]; then
291+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
292+
echo "arch_name=amd64" >> $GITHUB_OUTPUT
293+
else
294+
echo "arch_name=arm64" >> $GITHUB_OUTPUT
295+
fi
296+
else
297+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
298+
echo "arch_name=x86_64" >> $GITHUB_OUTPUT
299+
else
300+
echo "arch_name=aarch64" >> $GITHUB_OUTPUT
301+
fi
302+
fi
303+
307304
- name: Upload Artifact
308305
uses: actions/upload-artifact@v4
309306
with:
310-
name: Deb Installer
311-
path: ./package/out/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
307+
name: Linux-${{ matrix.format }}-${{ matrix.arch }}-Installer
308+
path: ./package/out/quarto-${{needs.configure.outputs.version}}-linux-${{ steps.pkg_arch.outputs.arch_name }}.${{ matrix.format }}
312309

313310
test-tarball-linux:
314311
runs-on: ubuntu-latest
@@ -595,8 +592,7 @@ jobs:
595592
runs-on: ubuntu-latest
596593
needs: [
597594
configure,
598-
make-installer-deb,
599-
make-installer-arm64-deb,
595+
make-installer-linux,
600596
make-installer-win,
601597
make-installer-mac,
602598
# optional in release to not be blocked by RHEL build depending on conda-forge deno dependency
@@ -662,13 +658,21 @@ jobs:
662658
sha256sum quarto-${{needs.configure.outputs.version}}-linux-arm64.tar.gz >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
663659
popd
664660
665-
pushd Deb\ Installer
661+
pushd Linux-deb-x86_64-Installer
666662
sha256sum quarto-${{needs.configure.outputs.version}}-linux-amd64.deb >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
667663
popd
668664
669-
pushd Deb\ Arm64\ Installer
665+
pushd Linux-deb-aarch64-Installer
670666
sha256sum quarto-${{needs.configure.outputs.version}}-linux-arm64.deb >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
671-
popd
667+
popd
668+
669+
pushd Linux-rpm-x86_64-Installer
670+
sha256sum quarto-${{needs.configure.outputs.version}}-linux-x86_64.rpm >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
671+
popd
672+
673+
pushd Linux-rpm-aarch64-Installer
674+
sha256sum quarto-${{needs.configure.outputs.version}}-linux-aarch64.rpm >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
675+
popd
672676
673677
pushd Source
674678
sha256sum quarto-${{needs.configure.outputs.version}}.tar.gz >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
@@ -692,8 +696,10 @@ jobs:
692696
./Deb Zip/quarto-${{needs.configure.outputs.version}}-linux-amd64.tar.gz
693697
./Deb Arm64 Zip/quarto-${{needs.configure.outputs.version}}-linux-arm64.tar.gz
694698
./RHEL Zip/quarto-${{needs.configure.outputs.version}}-linux-rhel7-amd64.tar.gz
695-
./Deb Installer/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
696-
./Deb Arm64 Installer/quarto-${{needs.configure.outputs.version}}-linux-arm64.deb
699+
./Linux-deb-x86_64-Installer/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
700+
./Linux-deb-aarch64-Installer/quarto-${{needs.configure.outputs.version}}-linux-arm64.deb
701+
./Linux-rpm-x86_64-Installer/quarto-${{needs.configure.outputs.version}}-linux-x86_64.rpm
702+
./Linux-rpm-aarch64-Installer/quarto-${{needs.configure.outputs.version}}-linux-aarch64.rpm
697703
./Windows Installer/quarto-${{needs.configure.outputs.version}}-win.msi
698704
./Windows Zip/quarto-${{needs.configure.outputs.version}}-win.zip
699705
./Mac Installer/quarto-${{needs.configure.outputs.version}}-macos.pkg
@@ -705,8 +711,7 @@ jobs:
705711
if: ${{ (failure() || cancelled()) && inputs.publish-release }}
706712
needs: [
707713
configure,
708-
make-installer-deb,
709-
make-installer-arm64-deb,
714+
make-installer-linux,
710715
make-installer-win,
711716
make-installer-mac,
712717
# optional in release to not be blocked by RHEL build depending on conda-forge deno dependency
@@ -763,10 +768,62 @@ jobs:
763768

764769
- uses: ./.github/actions/docker
765770
with:
766-
source: ./Deb Installer/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
771+
source: ./Linux-deb-x86_64-Installer/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
767772
version: ${{needs.configure.outputs.version}}
768773
token: ${{ secrets.GITHUB_TOKEN }}
769774
username: ${{ github.actor }}
770775
org: ${{ github.repository_owner }}
771776
name: quarto
772777
daily: ${{ inputs.pre-release }}
778+
779+
cloudsmith-push:
780+
if: ${{ inputs.publish-release }}
781+
runs-on: ubuntu-latest
782+
needs: [configure, publish-release]
783+
strategy:
784+
matrix:
785+
arch: [x86_64, aarch64]
786+
format: [deb, rpm]
787+
repo: [open, pro]
788+
steps:
789+
- uses: actions/checkout@v4
790+
with:
791+
sparse-checkout: |
792+
.github
793+
794+
- name: Prevent Re-run
795+
if: ${{ inputs.publish-release }}
796+
uses: ./.github/workflows/actions/prevent-rerun
797+
798+
- name: Download Artifacts
799+
uses: actions/download-artifact@v4
800+
801+
- name: Set package file name
802+
id: pkg_file
803+
run: |
804+
if [ "${{ matrix.format }}" == "deb" ]; then
805+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
806+
echo "arch_name=amd64" >> $GITHUB_OUTPUT
807+
else
808+
echo "arch_name=arm64" >> $GITHUB_OUTPUT
809+
fi
810+
else
811+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
812+
echo "arch_name=x86_64" >> $GITHUB_OUTPUT
813+
else
814+
echo "arch_name=aarch64" >> $GITHUB_OUTPUT
815+
fi
816+
fi
817+
818+
- name: Push ${{ matrix.format }} ${{ matrix.arch }} to Cloudsmith ${{ matrix.repo }}
819+
uses: cloudsmith-io/action@master
820+
with:
821+
api-key: ${{ secrets.CLOUDSMITH_API_KEY }}
822+
command: "push"
823+
format: "${{ matrix.format }}"
824+
owner: "posit"
825+
repo: "${{ matrix.repo }}"
826+
distro: "any-distro"
827+
release: "any-version"
828+
republish: "true"
829+
file: "./Linux-${{ matrix.format }}-${{ matrix.arch }}-Installer/quarto-${{needs.configure.outputs.version}}-linux-${{ steps.pkg_file.outputs.arch_name }}.${{ matrix.format }}"

package/scripts/linux/rpm/postinst

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
# detect whether running as root (per machine installation)
5+
# if per machine (run without sudo):
6+
7+
if [[ $EUID -eq 0 ]]; then
8+
if [ -d "/usr/local/bin" ]
9+
then
10+
ln -fs /opt/quarto/bin/quarto /usr/local/bin/quarto
11+
else
12+
echo "Quarto symlink not created, please be sure that you add Quarto to your path."
13+
fi
14+
15+
if [ -d "/usr/local/man/man1" ]
16+
then
17+
ln -fs /opt/quarto/share/man/quarto.man /usr/local/man/man1/quarto.1
18+
elif [ -d "/usr/local/man" ]
19+
then
20+
ln -fs /opt/quarto/share/man/quarto.man /usr/local/man/quarto.1
21+
fi
22+
23+
else
24+
if [ -d "~/bin/quarto" ]
25+
then
26+
ln -fs /opt/quarto/bin/quarto ~/bin/quarto
27+
else
28+
echo "Quarto symlink not created, please be sure that you add Quarto to your path."
29+
fi
30+
31+
if [ -d "~/man/man1" ]
32+
then
33+
ln -fs /opt/quarto/share/man/quarto.man ~/man/man1/quarto.1
34+
elif [ -d "~/man" ]
35+
then
36+
ln -fs /opt/quarto/share/man/quarto.man ~/man/quarto.1
37+
fi
38+
39+
fi
40+
41+
# Figure architecture
42+
NIXARCH=$(uname -m)
43+
if [[ $NIXARCH == "aarch64" ]]; then
44+
ARCH_DIR=aarch64
45+
else
46+
ARCH_DIR=x86_64
47+
fi
48+
49+
ln -fs /opt/quarto/bin/tools/${ARCH_DIR}/pandoc /opt/quarto/bin/tools/pandoc
50+
51+
exit 0

package/scripts/linux/rpm/postrm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
if [[ "$EUID" -eq 0 ]]
5+
then
6+
rm -f /usr/local/bin/quarto
7+
else
8+
rm -f ~/bin/quarto
9+
fi
10+
11+
# Remove pandoc symlink created by postinst
12+
# (before 1.4 this was a regular file that shouldn't be removed here)
13+
pandoc=/opt/quarto/bin/tools/pandoc
14+
if [ -h "$pandoc" ]
15+
then
16+
rm -f "$pandoc"
17+
fi
18+
19+
exit 0

package/src/bld.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { mainRunner } from "../../src/core/main.ts";
1010

1111
import { prepareDist } from "./common/prepare-dist.ts";
1212
import { updateHtmlDependencies } from "./common/update-html-dependencies.ts";
13-
import { makeInstallerDeb } from "./linux/installer.ts";
13+
import { makeInstallerDeb, makeInstallerRpm } from "./linux/installer.ts";
1414
import { makeInstallerMac } from "./macos/installer.ts";
1515
import {
1616
compileQuartoLatexmkCommand,
@@ -96,6 +96,10 @@ function getCommands() {
9696
packageCommand(makeInstallerDeb, "make-installer-deb")
9797
.description("Builds Linux deb installer"),
9898
);
99+
commands.push(
100+
packageCommand(makeInstallerRpm, "make-installer-rpm")
101+
.description("Builds Linux rpm installer"),
102+
);
99103
commands.push(
100104
packageCommand(makeInstallerWindows, "make-installer-win")
101105
.description("Builds Windows installer"),

0 commit comments

Comments
 (0)