Skip to content

Commit 312db36

Browse files
committed
gha - add new workflow to build rpm release
1 parent 401b50b commit 312db36

2 files changed

Lines changed: 252 additions & 47 deletions

File tree

.github/workflows/create-release.yml

Lines changed: 64 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 }}
@@ -194,6 +197,8 @@ jobs:
194197

195198
make-tarball-rhel:
196199
runs-on: ubuntu-latest
200+
# temporarily disable due to unavailability of latest deno in conda-forge
201+
if: false
197202
needs: [configure]
198203
steps:
199204
- uses: actions/checkout@v4
@@ -240,9 +245,13 @@ jobs:
240245
name: RHEL Zip
241246
path: ./package/quarto-${{needs.configure.outputs.version}}-linux-rhel7-amd64.tar.gz
242247

243-
make-installer-arm64-deb:
248+
make-installer-linux:
244249
runs-on: ubuntu-latest
245250
needs: [configure]
251+
strategy:
252+
matrix:
253+
arch: [x86_64, aarch64]
254+
format: [deb, rpm]
246255
steps:
247256
- uses: actions/checkout@v4
248257
with:
@@ -256,57 +265,47 @@ jobs:
256265
run: |
257266
./configure.sh
258267
259-
- name: Prepare Distribution
268+
- name: Install nfpm
260269
run: |
261-
pushd package/src/
262-
./quarto-bld prepare-dist --set-version ${{needs.configure.outputs.version}} --arch aarch64 --log-level info
263-
popd
264-
265-
- name: Make Installer
266-
run: |
267-
pushd package/src/
268-
./quarto-bld make-installer-deb --set-version ${{needs.configure.outputs.version}} --arch aarch64 --log-level info
269-
popd
270-
271-
- name: Upload Artifact
272-
uses: actions/upload-artifact@v4
273-
with:
274-
name: Deb Arm64 Installer
275-
path: ./package/out/quarto-${{needs.configure.outputs.version}}-linux-arm64.deb
276-
277-
make-installer-deb:
278-
runs-on: ubuntu-latest
279-
needs: [configure]
280-
steps:
281-
- uses: actions/checkout@v4
282-
with:
283-
ref: ${{ needs.configure.outputs.version_commit }}
284-
285-
- name: Prevent Re-run
286-
if: ${{ inputs.publish-release }}
287-
uses: ./.github/workflows/actions/prevent-rerun
288-
289-
- name: Configure
290-
run: |
291-
./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
292274
293275
- name: Prepare Distribution
294276
run: |
295277
pushd package/src/
296-
./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
297279
popd
298280
299281
- name: Make Installer
300282
run: |
301283
pushd package/src/
302-
./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
303285
popd
304286
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+
305304
- name: Upload Artifact
306305
uses: actions/upload-artifact@v4
307306
with:
308-
name: Deb Installer
309-
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 }}
310309

311310
test-tarball-linux:
312311
runs-on: ubuntu-latest
@@ -593,8 +592,7 @@ jobs:
593592
runs-on: ubuntu-latest
594593
needs: [
595594
configure,
596-
make-installer-deb,
597-
make-installer-arm64-deb,
595+
make-installer-linux,
598596
make-installer-win,
599597
make-installer-mac,
600598
# optional in release to not be blocked by RHEL build depending on conda-forge deno dependency
@@ -660,13 +658,21 @@ jobs:
660658
sha256sum quarto-${{needs.configure.outputs.version}}-linux-arm64.tar.gz >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
661659
popd
662660
663-
pushd Deb\ Installer
661+
pushd Linux-deb-x86_64-Installer
664662
sha256sum quarto-${{needs.configure.outputs.version}}-linux-amd64.deb >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
665663
popd
666664
667-
pushd Deb\ Arm64\ Installer
665+
pushd Linux-deb-aarch64-Installer
668666
sha256sum quarto-${{needs.configure.outputs.version}}-linux-arm64.deb >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
669-
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
670676
671677
pushd Source
672678
sha256sum quarto-${{needs.configure.outputs.version}}.tar.gz >> ../quarto-${{needs.configure.outputs.version}}-checksums.txt
@@ -690,8 +696,10 @@ jobs:
690696
./Deb Zip/quarto-${{needs.configure.outputs.version}}-linux-amd64.tar.gz
691697
./Deb Arm64 Zip/quarto-${{needs.configure.outputs.version}}-linux-arm64.tar.gz
692698
./RHEL Zip/quarto-${{needs.configure.outputs.version}}-linux-rhel7-amd64.tar.gz
693-
./Deb Installer/quarto-${{needs.configure.outputs.version}}-linux-amd64.deb
694-
./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
695703
./Windows Installer/quarto-${{needs.configure.outputs.version}}-win.msi
696704
./Windows Zip/quarto-${{needs.configure.outputs.version}}-win.zip
697705
./Mac Installer/quarto-${{needs.configure.outputs.version}}-macos.pkg
@@ -703,8 +711,7 @@ jobs:
703711
if: ${{ (failure() || cancelled()) && inputs.publish-release }}
704712
needs: [
705713
configure,
706-
make-installer-deb,
707-
make-installer-arm64-deb,
714+
make-installer-linux,
708715
make-installer-win,
709716
make-installer-mac,
710717
# optional in release to not be blocked by RHEL build depending on conda-forge deno dependency
@@ -761,10 +768,20 @@ jobs:
761768

762769
- uses: ./.github/actions/docker
763770
with:
764-
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
765772
version: ${{needs.configure.outputs.version}}
766773
token: ${{ secrets.GITHUB_TOKEN }}
767774
username: ${{ github.actor }}
768775
org: ${{ github.repository_owner }}
769776
name: quarto
770777
daily: ${{ inputs.pre-release }}
778+
779+
call-cloudsmith-publish:
780+
if: ${{ inputs.publish-release && ! (inputs.pre-release == true) }}
781+
needs: [configure, publish-release]
782+
uses: ./.github/workflows/publish-cloudsmith.yml
783+
with:
784+
version: ${{ needs.configure.outputs.tag_name }}
785+
dry-run: false
786+
secrets:
787+
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
name: Publish to Cloudsmith
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Release version/tag (e.g., v1.9.123 or 1.9.123, or 'latest' for most recent)"
8+
required: false
9+
type: string
10+
default: "latest"
11+
dry-run:
12+
description: "Dry run (don't actually publish)"
13+
required: false
14+
type: boolean
15+
default: true
16+
workflow_call:
17+
inputs:
18+
version:
19+
description: "Release version/tag"
20+
required: true
21+
type: string
22+
dry-run:
23+
description: "Dry run (don't actually publish)"
24+
required: false
25+
type: boolean
26+
default: false
27+
secrets:
28+
CLOUDSMITH_API_KEY:
29+
required: true
30+
31+
jobs:
32+
determine-version:
33+
runs-on: ubuntu-latest
34+
outputs:
35+
tag_name: ${{ steps.resolve.outputs.tag_name }}
36+
version: ${{ steps.resolve.outputs.version }}
37+
is_prerelease: ${{ steps.resolve.outputs.is_prerelease }}
38+
steps:
39+
- uses: actions/checkout@v4
40+
with:
41+
sparse-checkout: |
42+
.github
43+
44+
- name: Resolve version and tag
45+
id: resolve
46+
run: |
47+
VERSION_INPUT="${{ inputs.version }}"
48+
49+
# If version is "latest" or empty, get the latest release
50+
if [ "$VERSION_INPUT" == "latest" ] || [ -z "$VERSION_INPUT" ]; then
51+
echo "Fetching latest release..."
52+
TAG_NAME=$(gh release list --limit 1 --json tagName --jq '.[0].tagName')
53+
IS_PRERELEASE=$(gh release view "$TAG_NAME" --json isPrerelease --jq '.isPrerelease')
54+
else
55+
# Ensure tag has 'v' prefix
56+
if [[ "$VERSION_INPUT" == v* ]]; then
57+
TAG_NAME="$VERSION_INPUT"
58+
else
59+
TAG_NAME="v$VERSION_INPUT"
60+
fi
61+
62+
# Check if release exists and get prerelease status
63+
if ! gh release view "$TAG_NAME" > /dev/null 2>&1; then
64+
echo "::error::Release $TAG_NAME not found"
65+
exit 1
66+
fi
67+
IS_PRERELEASE=$(gh release view "$TAG_NAME" --json isPrerelease --jq '.isPrerelease')
68+
fi
69+
70+
# Extract version without 'v' prefix
71+
VERSION="${TAG_NAME#v}"
72+
73+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
74+
echo "version=$VERSION" >> $GITHUB_OUTPUT
75+
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
76+
77+
echo "Resolved to: $TAG_NAME (version: $VERSION, prerelease: $IS_PRERELEASE)"
78+
env:
79+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80+
81+
- name: Check not prerelease
82+
if: steps.resolve.outputs.is_prerelease == 'true'
83+
run: |
84+
echo "::error::Release ${{ steps.resolve.outputs.tag_name }} is a prerelease. Cloudsmith publishing is only for stable releases."
85+
exit 1
86+
87+
validate-all-assets:
88+
runs-on: ubuntu-latest
89+
needs: [determine-version]
90+
steps:
91+
- name: Validate all packages exist in release
92+
run: |
93+
TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
94+
VERSION="${{ needs.determine-version.outputs.version }}"
95+
96+
echo "Validating packages for release $TAG_NAME..."
97+
98+
# Get list of assets from release (API call, no download)
99+
ASSETS=$(gh release view "$TAG_NAME" --json assets --jq '.assets[].name')
100+
101+
MISSING=0
102+
REQUIRED_FILES=(
103+
"quarto-${VERSION}-linux-amd64.deb"
104+
"quarto-${VERSION}-linux-arm64.deb"
105+
"quarto-${VERSION}-linux-x86_64.rpm"
106+
"quarto-${VERSION}-linux-aarch64.rpm"
107+
)
108+
109+
for FILE in "${REQUIRED_FILES[@]}"; do
110+
if echo "$ASSETS" | grep -q "^${FILE}$"; then
111+
echo "✓ Found: $FILE"
112+
else
113+
echo "::error::Missing: $FILE"
114+
MISSING=$((MISSING + 1))
115+
fi
116+
done
117+
118+
if [ $MISSING -gt 0 ]; then
119+
echo "::error::$MISSING package(s) missing from release. All 4 packages required for Cloudsmith publishing."
120+
exit 1
121+
fi
122+
123+
echo "All required packages present in release"
124+
env:
125+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
126+
GH_REPO: quarto-dev/quarto-cli
127+
128+
publish-cloudsmith:
129+
runs-on: ubuntu-latest
130+
needs: [determine-version, validate-all-assets]
131+
strategy:
132+
matrix:
133+
arch: [x86_64, aarch64]
134+
format: [deb, rpm]
135+
steps:
136+
- name: Set package architecture name
137+
id: pkg_arch
138+
run: |
139+
if [ "${{ matrix.format }}" == "deb" ]; then
140+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
141+
echo "arch_name=amd64" >> $GITHUB_OUTPUT
142+
else
143+
echo "arch_name=arm64" >> $GITHUB_OUTPUT
144+
fi
145+
else
146+
if [ "${{ matrix.arch }}" == "x86_64" ]; then
147+
echo "arch_name=x86_64" >> $GITHUB_OUTPUT
148+
else
149+
echo "arch_name=aarch64" >> $GITHUB_OUTPUT
150+
fi
151+
fi
152+
153+
- name: Download and validate package from release
154+
run: |
155+
TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
156+
VERSION="${{ needs.determine-version.outputs.version }}"
157+
ARCH_NAME="${{ steps.pkg_arch.outputs.arch_name }}"
158+
FILE_NAME="quarto-${VERSION}-linux-${ARCH_NAME}.${{ matrix.format }}"
159+
160+
echo "Downloading $FILE_NAME from release $TAG_NAME..."
161+
162+
if ! gh release download "$TAG_NAME" --pattern "$FILE_NAME"; then
163+
echo "::error::Failed to download $FILE_NAME from release $TAG_NAME"
164+
exit 1
165+
fi
166+
167+
if [ ! -f "$FILE_NAME" ]; then
168+
echo "::error::Package file $FILE_NAME not found in release"
169+
exit 1
170+
fi
171+
172+
echo "✓ Successfully downloaded and validated: $FILE_NAME"
173+
env:
174+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
175+
GH_REPO: quarto-dev/quarto-cli
176+
177+
- name: Install and authenticate Cloudsmith CLI
178+
uses: cloudsmith-io/[email protected]
179+
with:
180+
api-key: ${{ secrets.CLOUDSMITH_API_KEY }}
181+
182+
- name: Push ${{ matrix.format }} ${{ matrix.arch }} to Cloudsmith${{ inputs.dry-run && ' (DRY RUN)' || '' }}
183+
run: |
184+
cloudsmith push ${{ matrix.format }} \
185+
posit/open/any-distro/any-version \
186+
"quarto-${{ needs.determine-version.outputs.version }}-linux-${{ steps.pkg_arch.outputs.arch_name }}.${{ matrix.format }}" \
187+
--republish \
188+
${{ inputs.dry-run && '--dry-run' || '' }}

0 commit comments

Comments
 (0)