Skip to content

Commit f6d07dd

Browse files
authored
Merge branch 'main' into main
2 parents aa7c2d3 + 45f5567 commit f6d07dd

File tree

61 files changed

+2669
-1401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2669
-1401
lines changed

.github/workflows/cleanup-caches.yml

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,51 @@ jobs:
1212
steps:
1313
- name: Cleanup
1414
run: |
15-
echo "Fetching list of cache keys"
16-
cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id')
15+
echo "::group::Fetching cache list for PR #${{ github.event.pull_request.number }}"
16+
echo "Branch ref: $BRANCH"
17+
18+
# Get full cache list with details for logging
19+
cacheList=$(gh cache list --ref $BRANCH --limit 100 --json id,key,sizeInBytes)
20+
cacheCount=$(echo "$cacheList" | jq '. | length')
21+
22+
echo "Found $cacheCount cache(s) for this PR"
23+
24+
if [ "$cacheCount" -gt 0 ]; then
25+
echo "Cache details:"
26+
echo "$cacheList" | jq -r '.[] | " - ID: \(.id) | Key: \(.key) | Size: \(.sizeInBytes | tonumber / 1024 / 1024 | floor)MB"'
27+
fi
28+
echo "::endgroup::"
29+
30+
if [ "$cacheCount" -eq 0 ]; then
31+
echo "No caches to delete"
32+
exit 0
33+
fi
34+
35+
# Extract just the IDs for deletion
36+
cacheKeysForPR=$(echo "$cacheList" | jq -r '.[].id')
1737
1838
## Setting this to not fail the workflow while deleting cache keys.
1939
set +e
20-
echo "Deleting caches..."
40+
41+
echo "::group::Deleting caches"
42+
deleted=0
43+
failed=0
44+
2145
for cacheKey in $cacheKeysForPR
2246
do
23-
gh cache delete $cacheKey
47+
echo "Deleting cache ID: $cacheKey"
48+
if gh cache delete $cacheKey; then
49+
echo " ✓ Successfully deleted cache $cacheKey"
50+
((deleted++))
51+
else
52+
echo " ✗ Failed to delete cache $cacheKey"
53+
((failed++))
54+
fi
2455
done
25-
echo "Done"
56+
57+
echo "::endgroup::"
58+
59+
echo "::notice::Cache cleanup complete: $deleted deleted, $failed failed out of $cacheCount total"
2660
env:
2761
GH_TOKEN: ${{ github.token }}
2862
GH_REPO: ${{ github.repository }}

.github/workflows/create-release.yml

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -776,54 +776,12 @@ jobs:
776776
name: quarto
777777
daily: ${{ inputs.pre-release }}
778778

779-
cloudsmith-push:
779+
call-cloudsmith-publish:
780780
if: ${{ inputs.publish-release && ! (inputs.pre-release == true) }}
781-
runs-on: ubuntu-latest
782781
needs: [configure, publish-release]
783-
strategy:
784-
matrix:
785-
arch: [x86_64, aarch64]
786-
format: [deb, rpm]
787-
repo: [open]
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 }}"
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' || '' }}

.github/workflows/test-smokes.yml

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ on:
3838
schedule:
3939
- cron: "0 6 * * *"
4040

41-
# this is require to cleanup julia cache
41+
# this is required to cleanup julia cache
4242
permissions:
4343
actions: write
4444
contents: read
@@ -139,6 +139,13 @@ jobs:
139139
sudo apt-get install -y libharfbuzz-dev libfribidi-dev
140140
sudo apt-get install -y poppler-utils
141141
142+
- name: Install rsvg-convert for SVG conversion tests
143+
# Only do it on linux runner, and only if we are running the relevant tests
144+
if: runner.os == 'Linux' && contains(inputs.buckets, 'render-pdf-svg-conversion')
145+
run: |
146+
sudo apt-get update -y
147+
sudo apt-get install -y librsvg2-bin
148+
142149
- name: Restore R packages
143150
working-directory: tests
144151
run: |
@@ -289,35 +296,9 @@ jobs:
289296
working-directory: tests
290297
shell: pwsh
291298

292-
- name: Create Pull Request for new tests timing
293-
if: matrix.time-test
294-
id: cpr
295-
uses: peter-evans/create-pull-request@v6
296-
with:
297-
token: ${{ secrets.GITHUB_TOKEN }}
298-
add-paths: tests/timing-for-ci.txt
299-
commit-message: |
300-
timing for new tests [auto PR]
301-
branch: updates/timing-for-ci
302-
delete-branch: true
303-
assignees: cderv
304-
reviewers: cderv
305-
title: |
306-
[CI] Update timing file
307-
body: |
308-
This PR was created automatically with new timing test file for our parallel smoke tests.
309-
Please review and merge to trigger a new build of the website.
310-
311-
- name: Check auto PR outputs
312-
if: steps.cpr.outcome == 'success'
313-
run: |
314-
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
315-
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
316-
echo "Pull Request Action Performed - ${{ steps.cpr.outputs.pull-request-operation }}"
317-
318299
- name: Upload test timing file
319300
uses: actions/upload-artifact@v4
320-
if: matrix.time-test && ( failure() || cancelled())
301+
if: matrix.time-test
321302
with:
322303
name: timed test file
323304
path: tests/timing-for-ci.txt

0 commit comments

Comments
 (0)