mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
Using the new yaml anchor feature, we can inline the upload_release workflow file without duplicating code. In combination with the matrix feature this allows us to remove quite a bit of duplication. I'm not sure why we didn't use matrix to begin with. This is also a preparation for a follow-up PR, that uses github environments to improve secret protection, since reusable workflows don't support environments. Testing: [manually triggered nightly release](https://github.com/servo/servo/actions/runs/24236862409) Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
313 lines
12 KiB
YAML
313 lines
12 KiB
YAML
name: Release
|
|
|
|
on:
|
|
schedule:
|
|
# Run at 22:15 pm, daily.
|
|
# To make sure it finishes in time before next WPT daily epoch run
|
|
- cron: '15 22 * * *'
|
|
workflow_dispatch:
|
|
inputs:
|
|
# Note: On scheduled runs `inputs.regular_release` will be `null`, which allows us to create
|
|
# defaults by using `${{ inputs.regular_release || 'my_default_value' }}` expressions.
|
|
regular_release:
|
|
description: '`true` to create a release on this repo, false to release to the nightly-releases repo'
|
|
type: boolean
|
|
default: false
|
|
crates_io:
|
|
description: '`true` to publish to crates.io'
|
|
type: boolean
|
|
default: false
|
|
release_tag:
|
|
required: true
|
|
type: string
|
|
description: 'The tag to create for the release'
|
|
env:
|
|
RUST_BACKTRACE: 1
|
|
SHELL: /bin/bash
|
|
RELEASE_REPO: ${{ github.repository_owner }}/${{ inputs.regular_release && 'servo' || 'servo-nightly-builds' }}
|
|
|
|
jobs:
|
|
create-draft-release:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Create Draft GH Release
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- id: create-release
|
|
run: |
|
|
if [[ "${{ inputs.release_tag }}" != "" ]]; then
|
|
RELEASE_TAG="${{ inputs.release_tag }}"
|
|
RELEASE_NOTES="Servo release ${{ inputs.release_tag }}"
|
|
else
|
|
RELEASE_TAG=$(date "+%F")
|
|
RELEASE_NOTES="Nightly build based on servo/servo@${{ github.sha }}"
|
|
fi
|
|
RELEASE_URL=$(gh release create "${RELEASE_TAG}" \
|
|
--draft \
|
|
--title "${RELEASE_TAG}" \
|
|
--notes "${RELEASE_NOTES}" \
|
|
--repo ${RELEASE_REPO})
|
|
TEMP_TAG=$(basename "$RELEASE_URL")
|
|
RELEASE_ID=$( \
|
|
gh api -H "Accept: application/vnd.github+json" \
|
|
-H "X-GitHub-Api-Version: 2026-03-10" \
|
|
"/repos/${RELEASE_REPO}/releases/tags/${TEMP_TAG}" \
|
|
| jq '.id' \
|
|
)
|
|
echo "RELEASE_ID=${RELEASE_ID}" >> ${GITHUB_OUTPUT}
|
|
echo "RELEASE_TAG=${RELEASE_TAG}" >> ${GITHUB_OUTPUT}
|
|
env:
|
|
GITHUB_TOKEN: ${{ inputs.regular_release && github.token || secrets.NIGHTLY_REPO_TOKEN }}
|
|
outputs:
|
|
release-id: ${{ steps.create-release.outputs.RELEASE_ID }}
|
|
release-tag: ${{ steps.create-release.outputs.RELEASE_TAG }}
|
|
|
|
publish-nightly-release:
|
|
# We only auto-publish nightly releases, so we do not use this job for regular releases.
|
|
if: |
|
|
always()
|
|
&& (github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch')
|
|
&& (inputs.regular_release || false) == false
|
|
name: Publish GH Release
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Publish release (success)
|
|
if: ${{ !contains(needs.*.result, 'failure') && (!contains(needs.*.result, 'cancelled') && !cancelled()) }}
|
|
env:
|
|
MAKE_LATEST: ${{ github.event_name == 'schedule' && 'true' || 'false' }}
|
|
run: |
|
|
gh api \
|
|
--method PATCH \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "X-GitHub-Api-Version: 2026-03-10" \
|
|
/repos/${RELEASE_REPO}/releases/${RELEASE_ID} \
|
|
-F draft=false \
|
|
-f make_latest="${MAKE_LATEST}"
|
|
- name: Publish release (failure)
|
|
if: ${{ contains(needs.*.result, 'failure') || (contains(needs.*.result, 'cancelled') || cancelled()) }}
|
|
run: |
|
|
gh api \
|
|
--method PATCH \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "X-GitHub-Api-Version: 2026-03-10" \
|
|
/repos/${RELEASE_REPO}/releases/${RELEASE_ID} \
|
|
-F prerelease=true \
|
|
-F draft=false \
|
|
-f make_latest=false
|
|
env:
|
|
GITHUB_TOKEN: ${{ inputs.regular_release && github.token || secrets.NIGHTLY_REPO_TOKEN }}
|
|
RELEASE_ID: ${{ needs.create-draft-release.outputs.release-id }}
|
|
needs:
|
|
- create-draft-release
|
|
- upload-vendored-source
|
|
- upload-artifacts-nightly
|
|
- upload-artifacts-release
|
|
|
|
publish-crates-io:
|
|
name: 'Publish to crates.io'
|
|
if: github.repository == 'servo/servo' && (inputs.crates_io || false)
|
|
environment:
|
|
name: publish_crates_io
|
|
deployment: false
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- uses: rust-lang/crates-io-auth-action@v1
|
|
id: auth
|
|
- name: Publish to crates.io
|
|
env:
|
|
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
|
|
SERVO_CRATES_IO_SLEEP_AFTER_PUBLISH_SECONDS: "30"
|
|
SERVO_CRATES_IO_VERIFY_PUBLISHED_TIMEOUT_SECONDS: "300"
|
|
SERVO_CRATES_IO_VERIFY_PUBLISHED_INTERVAL_SECONDS: "10"
|
|
# Verification requires building, which is incredibly slow and also increases our attack surface.
|
|
# If we decide for an extra verification, we should add a seperate job before this one, which
|
|
# does a `dry-run` publish without any elevated permissions.
|
|
run: |
|
|
python3 etc/ci/publish_crates_io.py --no-verify
|
|
|
|
build-win:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build production release (Windows)
|
|
uses: ./.github/workflows/windows.yml
|
|
with:
|
|
profile: "production"
|
|
upload_zip: true
|
|
force-github-hosted-runner: true # <https://github.com/servo/servo/issues/33296>
|
|
|
|
upload-vendored-source:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Upload vendored source archive
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
attestations: write
|
|
env:
|
|
ARTIFACT_BASENAME: "servo-${{ needs.create-draft-release.outputs.release-tag }}-src-vendored"
|
|
ARTIFACT_FILENAME: "servo-${{ needs.create-draft-release.outputs.release-tag }}-src-vendored.tar.gz"
|
|
needs:
|
|
- create-draft-release
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 1
|
|
- name: Generate vendored archive
|
|
run: |
|
|
python3 etc/vendor_servo.py --filename "${ARTIFACT_BASENAME}"
|
|
- name: Generate artifact attestation
|
|
uses: actions/attest-build-provenance@v3
|
|
with:
|
|
subject-path: ${{ env.ARTIFACT_FILENAME }}
|
|
- name: Upload vendored archive to release
|
|
run: |
|
|
gh release upload "${{ needs.create-draft-release.outputs.release-tag }}" \
|
|
"${ARTIFACT_FILENAME}" \
|
|
--repo "${RELEASE_REPO}"
|
|
env:
|
|
GITHUB_TOKEN: ${{ inputs.regular_release && github.token || secrets.NIGHTLY_REPO_TOKEN }}
|
|
|
|
upload-artifacts-nightly:
|
|
# Only run scheduled nightly builds on upstream servo.
|
|
if: |
|
|
(github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch')
|
|
&& (inputs.regular_release || false) == false
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
id-token: write
|
|
attestations: write
|
|
needs: &upload-artifacts-needs
|
|
- create-draft-release
|
|
- build-win
|
|
- build-mac
|
|
- build-mac-arm64
|
|
- build-linux
|
|
- build-android
|
|
- build-ohos
|
|
strategy: &upload-artifacts-strategy
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- artifact_ids: ${{ needs.build-win.outputs.artifact_ids }}
|
|
artifact_platform: windows-msvc
|
|
- artifact_ids: ${{ needs.build-mac.outputs.artifact_ids }}
|
|
artifact_platform: mac
|
|
- artifact_ids: ${{ needs.build-mac-arm64.outputs.artifact_ids }}
|
|
artifact_platform: mac-arm64
|
|
- artifact_ids: ${{ needs.build-linux.outputs.artifact_ids }}
|
|
artifact_platform: linux
|
|
- artifact_ids: ${{ needs.build-android.outputs.artifact_ids }}
|
|
artifact_platform: android
|
|
- artifact_ids: ${{ needs.build-ohos.outputs.artifact_ids }}
|
|
artifact_platform: ohos
|
|
env:
|
|
ARTIFACT_IDS: ${{ matrix.artifact_ids }}
|
|
ARTIFACT_PLATFORM: ${{ matrix.artifact_platform }}
|
|
GITHUB_RELEASE_ID: ${{ needs.create-draft-release.outputs.release-id }}
|
|
RELEASE_REPO: ${{ github.repository_owner }}/servo-nightly-builds
|
|
RELEASE_REPO_TOKEN: ${{ secrets.NIGHTLY_REPO_TOKEN }}
|
|
S3_UPLOAD_CREDENTIALS: ${{ secrets.S3_UPLOAD_CREDENTIALS }}
|
|
steps: &upload-artifacts-steps
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
sparse-checkout: |
|
|
.github
|
|
etc/ci
|
|
fetch-depth: '1'
|
|
- name: Setup Python
|
|
uses: ./.github/actions/setup-python
|
|
- name: Validate artifact IDs
|
|
run: |
|
|
if [[ -z "${ARTIFACT_IDS}" ]]; then
|
|
echo "Error: No artifact IDs provided."
|
|
echo "Help: Check the build job's outputs.artifact_ids value."
|
|
echo "If you recently renamed the build job without updating the corresponding output reference,"
|
|
echo "that is likely the cause of this error."
|
|
exit 1
|
|
fi
|
|
- uses: actions/download-artifact@v8
|
|
with:
|
|
artifact-ids: ${{ env.ARTIFACT_IDS }}
|
|
merge-multiple: true
|
|
path: release-artifacts
|
|
- name: Generate artifact attestation
|
|
uses: actions/attest-build-provenance@v3
|
|
with:
|
|
subject-path: 'release-artifacts/*'
|
|
- name: Upload release artifacts
|
|
run: |
|
|
./etc/ci/upload_nightly.py "${ARTIFACT_PLATFORM}" \
|
|
--secret-from-environment \
|
|
--github-release-id "${GITHUB_RELEASE_ID}" \
|
|
release-artifacts/*
|
|
|
|
upload-artifacts-release:
|
|
if: github.event_name == 'workflow_dispatch' && inputs.regular_release
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
id-token: write
|
|
attestations: write
|
|
# Necessary for the github token to upload artifacts to the release.
|
|
contents: write
|
|
needs: *upload-artifacts-needs
|
|
strategy: *upload-artifacts-strategy
|
|
env:
|
|
ARTIFACT_IDS: ${{ matrix.artifact_ids }}
|
|
ARTIFACT_PLATFORM: ${{ matrix.artifact_platform }}
|
|
GITHUB_RELEASE_ID: ${{ needs.create-draft-release.outputs.release-id }}
|
|
RELEASE_REPO: ${{ github.repository_owner }}/servo
|
|
RELEASE_REPO_TOKEN: ${{ github.token }}
|
|
S3_UPLOAD_CREDENTIALS: ${{ secrets.S3_UPLOAD_CREDENTIALS }}
|
|
steps: *upload-artifacts-steps
|
|
|
|
|
|
build-mac:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build production release (macOS)
|
|
uses: ./.github/workflows/mac.yml
|
|
with:
|
|
profile: "production"
|
|
force-github-hosted-runner: true # <https://github.com/servo/servo/issues/33296>
|
|
|
|
build-mac-arm64:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build production release (macOS Arm64)
|
|
uses: ./.github/workflows/mac-arm64.yml
|
|
with:
|
|
profile: "production"
|
|
force-github-hosted-runner: true # <https://github.com/servo/servo/issues/33296>
|
|
|
|
build-linux:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build production release (Linux)
|
|
uses: ./.github/workflows/linux.yml
|
|
with:
|
|
profile: "production"
|
|
force-github-hosted-runner: true # <https://github.com/servo/servo/issues/33296>
|
|
|
|
build-android:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build release (Android)
|
|
uses: ./.github/workflows/android.yml
|
|
with:
|
|
profile: "release"
|
|
secrets: inherit
|
|
|
|
build-ohos:
|
|
# This job is only useful when run on upstream servo.
|
|
if: github.repository == 'servo/servo' || github.event_name == 'workflow_dispatch'
|
|
name: Build production release (OpenHarmony)
|
|
uses: ./.github/workflows/ohos.yml
|
|
with:
|
|
profile: "production"
|
|
upload_library: true
|
|
secrets: inherit
|