mirror of
https://github.com/warpdotdev/warp.git
synced 2026-06-04 17:56:28 +08:00
## Description - Stack this follow-up on #10971 so the link-normalization review stays focused. - Keep the stable-release Slack changelog payload readable and link-safe, including contributor/profile links. - Upload the generated raw Markdown changelog as a workflow artifact and add a Slack link to that artifact for easier oncall/client copy-paste workflows. ## Linked Issue N/A — release workflow follow-up. - [ ] The linked issue is labeled `ready-to-spec` or `ready-to-implement`. - [ ] Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes). ## Testing - `python3 -m py_compile .agents/skills/changelog-draft/scripts/build_slack_payload.py .agents/skills/changelog-draft/scripts/convert_to_release_json.py .agents/skills/changelog-draft/scripts/fetch_issue_reporters.py` - Local Slack payload regression covering: - Markdown PR/profile link conversion to Slack `<url|label>` links - raw Markdown artifact link block generation - percent-encoding of Slack link delimiters (`|`, `<`, `>`) in Markdown URLs and artifact URLs - Ruby YAML parse of `.github/workflows/create_release.yml` - `git diff --check` - `cargo fmt` - `cargo clippy --workspace --all-targets --all-features --tests -- -D warnings` - [ ] I have manually tested my changes locally with `./script/run` ### Example Slack output Representative generated Slack text after this PR, with the artifact URL shortened here for readability: **Header** Changelog for v0.2026.05.20.09.21.stable_00 **Artifact block** Raw Markdown changelog: <https://github.com/warpdotdev/warp-internal/actions/runs/.../artifacts/...|Download raw Markdown changelog artifact> **Changelog block** *New Features* • Added tab dragging between windows. (<https://github.com/warpdotdev/warp/pull/9275|#9275>) *Improvements* • Added `warposs://pane/{uuid}` deep links. (<https://github.com/warpdotdev/warp/pull/9655|#9655>) — <https://github.com/Akeuuh|@Akeuuh> ✨ *Bug Fixes* • Fixed file picker path truncation. (<https://github.com/warpdotdev/warp/pull/9885|#9885>) — <https://github.com/bradleyjames|@bradleyjames> ✨ *oz_updates* • Configurable max context window per profile. (<https://github.com/warpdotdev/warp/pull/9352|#9352>) ### Screenshots / Videos Not applicable for this release workflow change. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode ## Agent context - Conversation: https://staging.warp.dev/conversation/f4d16867-0550-46b3-bf0e-7509d9bbbe9e - Plan: https://staging.warp.dev/drive/notebook/P70nhN6zYmnv5PsxrcEkJ0 Co-Authored-By: Oz <oz-agent@warp.dev> --------- Co-authored-by: Oz <oz-agent@warp.dev>
1808 lines
81 KiB
YAML
1808 lines
81 KiB
YAML
# A reusable workflow that encapsulates all of the logic surrounding building
|
|
# all bundles for a single release channel, either new releases (when run on the
|
|
# `master` branch) or updated release candidates (when run within a `*_release`
|
|
# branch).
|
|
#
|
|
# This can either be triggered:
|
|
# * Indirectly, using workflow_call, for creating real releases.
|
|
# * Directly, using workflow_dispatch, for testing. By default, this will not create GitHub or Sentry releases, or upload to GCS.
|
|
|
|
name: Create Release
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
channel:
|
|
description: The channel to create a release or release candidate for.
|
|
required: true
|
|
type: string
|
|
build_linux:
|
|
description: Build Linux artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_windows:
|
|
description: Build Windows artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_macos:
|
|
description: Build macOS artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_web:
|
|
description: Build web artifacts.
|
|
type: boolean
|
|
default: true
|
|
should_publish:
|
|
description: Publish this release
|
|
type: boolean
|
|
default: true
|
|
workflow_dispatch:
|
|
inputs:
|
|
channel:
|
|
type: string
|
|
required: true
|
|
build_linux:
|
|
description: Build Linux artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_windows:
|
|
description: Build Windows artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_macos:
|
|
description: Build macOS artifacts.
|
|
type: boolean
|
|
default: true
|
|
build_web:
|
|
description: Build web artifacts.
|
|
type: boolean
|
|
default: true
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
CONFIG_FILE: ".github/workflows/release_configurations.json"
|
|
|
|
jobs:
|
|
# Perform all once-per-release steps. Dependent jobs will build release
|
|
# assets and upload them as appropriate.
|
|
prepare_release:
|
|
name: Prepare release
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
release_branch: ${{ steps.create_branch_and_tag.outputs.branch }}
|
|
release_tag: ${{ steps.create_branch_and_tag.outputs.tag }}
|
|
should_publish: ${{ steps.set_publish.outputs.should_publish }}
|
|
steps:
|
|
- name: Checkout sources
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Set publish flag based on the workflow trigger
|
|
id: set_publish
|
|
run: |
|
|
# The should_publish input is only set on the workflow_call trigger.
|
|
# This means it's not possible to trigger publishing via workflow_dispatch, and
|
|
# publishing is enabled by default when called for a new release or RC.
|
|
if [[ "${{ inputs.should_publish }}" == "true" ]]; then
|
|
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "should_publish=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
shell: bash
|
|
|
|
- name: Update branch and tag
|
|
id: create_branch_and_tag
|
|
run: |
|
|
if [[ "${{ steps.set_publish.outputs.should_publish }}" == "true" ]]; then
|
|
GIT_BRANCH_NAME="${GITHUB_REF#refs/heads/}"
|
|
source ./script/create_release_tag_and_branch --channel $CHANNEL --branch-name "$GIT_BRANCH_NAME"
|
|
echo "branch=$(git branch --show-current)" >> $GITHUB_OUTPUT
|
|
echo "tag=$tag" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "branch=$(git branch --show-current)" >> $GITHUB_OUTPUT
|
|
# Use a fake version tag that will pass package validation.
|
|
echo "tag=v0.$GITHUB_SHA" >> $GITHUB_OUTPUT
|
|
fi
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
# See https://github.com/orgs/community/discussions/151442 for why we need to use
|
|
# a PAT here.
|
|
GITHUB_TOKEN: ${{ secrets.CREATE_RELEASE_TAG_PUSH_PAT }}
|
|
|
|
- name: Create GitHub release
|
|
if: ${{ steps.set_publish.outputs.should_publish == 'true' }}
|
|
id: create_release
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
name: ${{ steps.get-config.outputs.release_base_name }} ${{ steps.create_branch_and_tag.outputs.tag }}
|
|
tag_name: ${{ steps.create_branch_and_tag.outputs.tag }}
|
|
body: ${{ steps.get-config.outputs.release_body_text }}
|
|
draft: false
|
|
prerelease: ${{ steps.get-config.outputs.is_prerelease }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Create Sentry release
|
|
if: ${{ steps.set_publish.outputs.should_publish == 'true' }}
|
|
uses: getsentry/action-release@5657c9e888b4e2cc85f4d29143ea4131fde4a73a # v3.6.0
|
|
env:
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
SENTRY_ORG: warpdotdev
|
|
SENTRY_PROJECT: ${{ steps.get-config.outputs.sentry_project }}
|
|
with:
|
|
environment: ${{ steps.get-config.outputs.sentry_environment }}
|
|
version: ${{ steps.create_branch_and_tag.outputs.tag }}
|
|
|
|
release_macos_single_arch:
|
|
name: Build Release (macOS ${{ matrix.dmg_name_suffix }})
|
|
runs-on: macos-26-xlarge
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_macos != false }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: aarch64
|
|
dmg_name_suffix: arm64
|
|
- arch: x86_64
|
|
dmg_name_suffix: x86_64
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: macos
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
- name: Ensure rust target is installed
|
|
run: rustup target add ${{ matrix.arch }}-apple-darwin
|
|
shell: bash
|
|
|
|
# Install go toolchain, as it may be needed for some build steps.
|
|
- name: Setup Go
|
|
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
|
with:
|
|
go-version: stable
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Install cargo-bundle
|
|
run: script/install_cargo_bundle
|
|
|
|
- name: Install create-dmg
|
|
run: brew install create-dmg
|
|
|
|
- name: Build ${{ matrix.arch }} bundle
|
|
id: bundle_app
|
|
run: |
|
|
script/bundle --read-passwords-from-env --channel $CHANNEL --arch ${{ matrix.arch }} --dmg-name-suffix "${{ matrix.dmg_name_suffix }}"
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
WARP_DEVELOPER_ID_CERT: ${{ secrets.WARP_DEVELOPER_ID_CERT }}
|
|
WARP_DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.WARP_DEVELOPER_ID_CERT_PASSWORD }}
|
|
WARP_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.WARP_CODESIGN_KEYCHAIN_PASSWORD }}
|
|
WARP_NOTARIZATION_APPLE_ID: ${{ secrets.WARP_NOTARIZATION_APPLE_ID }}
|
|
WARP_NOTARIZATION_PASSWORD: ${{ secrets.WARP_NOTARIZATION_PASSWORD }}
|
|
|
|
- name: Add DMG to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload DMG to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload DMG as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-macos-${{ matrix.arch }}-${{ steps.get-config.outputs.channel }}
|
|
path: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debug symbols from frameworks to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.frameworks_dir }}
|
|
|
|
# Create a tar archive instead of simply using upload-artifact so we can
|
|
# preserve permissions and symlinks. If we don't preserve symlinks, we'll
|
|
# break the macOS framework directory structure.
|
|
- name: Create tar archive with build artifacts
|
|
run: |
|
|
tar czfv build-artifacts.tar.gz \
|
|
${{ steps.bundle_app.outputs.binary_path }} \
|
|
${{ steps.bundle_app.outputs.dock_tile_plugin_dir }} \
|
|
${{ steps.bundle_app.outputs.dsym_path }} \
|
|
${{ steps.bundle_app.outputs.dsym_realpath }} \
|
|
${{ steps.bundle_app.outputs.frameworks_dir }}
|
|
|
|
- name: Archive ${{ matrix.arch }} build artifacts for universal build
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: macos-${{ matrix.arch }}-${{ steps.get-config.outputs.channel }}
|
|
retention-days: 1
|
|
# We compress the tar archive, so no need to re-compress.
|
|
compression-level: 0
|
|
path: build-artifacts.tar.gz
|
|
|
|
release_macos_universal:
|
|
name: Build Release (macOS Universal)
|
|
runs-on: macos-26-xlarge
|
|
needs: [prepare_release, release_macos_single_arch]
|
|
if: ${{ inputs.build_macos != false }}
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: macos
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
# Install go toolchain, as it may be needed for some build steps.
|
|
- name: Setup Go
|
|
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
|
with:
|
|
go-version: stable
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Download aarch64 build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: macos-aarch64-${{ steps.get-config.outputs.channel }}
|
|
|
|
- name: Extract aarch64 build artifacts
|
|
run: tar xvfz build-artifacts.tar.gz
|
|
shell: bash
|
|
|
|
- name: Download x86_64 build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: macos-x86_64-${{ steps.get-config.outputs.channel }}
|
|
|
|
- name: Extract x86_64 build artifacts
|
|
run: tar xvfz build-artifacts.tar.gz
|
|
shell: bash
|
|
|
|
- name: Install cargo-bundle
|
|
run: script/install_cargo_bundle
|
|
|
|
- name: Install create-dmg
|
|
run: brew install create-dmg
|
|
|
|
- name: Bundle universal app
|
|
id: bundle_app
|
|
run: |
|
|
script/bundle --skip-build --read-passwords-from-env --channel $CHANNEL
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
WARP_DEVELOPER_ID_CERT: ${{ secrets.WARP_DEVELOPER_ID_CERT }}
|
|
WARP_DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.WARP_DEVELOPER_ID_CERT_PASSWORD }}
|
|
WARP_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.WARP_CODESIGN_KEYCHAIN_PASSWORD }}
|
|
WARP_NOTARIZATION_APPLE_ID: ${{ secrets.WARP_NOTARIZATION_APPLE_ID }}
|
|
WARP_NOTARIZATION_PASSWORD: ${{ secrets.WARP_NOTARIZATION_PASSWORD }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.dsym_folder_path }}
|
|
|
|
- name: Add DMG to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
id: upload_github_assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
# Continue if the upload fails; the next step will retry it.
|
|
continue-on-error: true
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Add DMG to GitHub release assets (retry 1/2)
|
|
id: upload_github_assets_retry
|
|
# If the first attempt failed, try again.
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' && steps.upload_github_assets.outcome == 'failure' }}
|
|
# Continue if the upload fails; the next step will retry it.
|
|
continue-on-error: true
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Add DMG to GitHub release assets (retry 2/2)
|
|
id: upload_github_assets_retry2
|
|
# If the first attempt failed, try again.
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' && steps.upload_github_assets_retry.outcome == 'failure' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload DMG to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload DMG as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-macos-universal-${{ steps.get-config.outputs.channel }}
|
|
path: ${{ steps.bundle_app.outputs.dmg_path }}
|
|
|
|
release_macos_cli:
|
|
name: Build Release (macOS CLI ${{ matrix.arch }})
|
|
runs-on: macos-26-xlarge
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_macos != false }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: aarch64
|
|
- arch: x86_64
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: macos
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
- name: Ensure rust target is installed
|
|
run: rustup target add ${{ matrix.arch }}-apple-darwin
|
|
shell: bash
|
|
|
|
# Install go toolchain, as it may be needed for some build steps.
|
|
- name: Setup Go
|
|
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
|
with:
|
|
go-version: stable
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Build ${{ matrix.arch }} binary
|
|
id: bundle_cli
|
|
run: |
|
|
script/bundle --read-passwords-from-env --channel $CHANNEL --arch ${{ matrix.arch }} --artifact cli
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
WARP_DEVELOPER_ID_CERT: ${{ secrets.WARP_DEVELOPER_ID_CERT }}
|
|
WARP_DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.WARP_DEVELOPER_ID_CERT_PASSWORD }}
|
|
WARP_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.WARP_CODESIGN_KEYCHAIN_PASSWORD }}
|
|
WARP_NOTARIZATION_APPLE_ID: ${{ secrets.WARP_NOTARIZATION_APPLE_ID }}
|
|
WARP_NOTARIZATION_PASSWORD: ${{ secrets.WARP_NOTARIZATION_PASSWORD }}
|
|
|
|
- name: Package CLI binary
|
|
run: |
|
|
mv ${{ steps.bundle_cli.outputs.binary_path }} oz-${{ steps.get-config.outputs.channel }}
|
|
tar czf oz-${{ steps.get-config.outputs.channel }}-macos-${{ matrix.arch }}.tar.gz oz-${{ steps.get-config.outputs.channel }} -C "$(dirname "${{ steps.bundle_cli.outputs.bundled_resources_dir }}")" resources
|
|
|
|
- name: Add CLI to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: oz-${{ steps.get-config.outputs.channel }}-macos-${{ matrix.arch }}.tar.gz
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload CLI to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: oz-${{ steps.get-config.outputs.channel }}-macos-${{ matrix.arch }}.tar.gz
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}/cli/macos/${{ matrix.arch }}
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload CLI as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-macos-cli-${{ matrix.arch }}-${{ steps.get-config.outputs.channel }}
|
|
path: oz-${{ steps.get-config.outputs.channel }}-macos-${{ matrix.arch }}.tar.gz
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_cli.outputs.dsym_path }}
|
|
|
|
release_linux_x86:
|
|
name: Build Release (Linux x86_64)
|
|
runs-on: namespace-profile-ubuntu-20-04
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_linux != false }}
|
|
timeout-minutes: 90
|
|
env:
|
|
# Automatically extract AppImages before running them instead of mounting
|
|
# them with FUSE, which isn't available on GitHub runners (and this is
|
|
# easier and less error-prone than trying to install it).
|
|
APPIMAGE_EXTRACT_AND_RUN: "1"
|
|
# Cache the generated settings schema so prepare_bundled_resources only
|
|
# compiles and runs the generator once per job instead of per-package.
|
|
SETTINGS_SCHEMA_CACHE: ${{ github.workspace }}/.settings_schema_cache.json
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: linux
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
# Install gcc 10, as gcc 9.5 has a bug with memcmp that is incompatible
|
|
# with aws-lc-rs (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189).
|
|
- name: Install and configure gcc-10
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install -y gcc-10 g++-10
|
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
|
gcc --version
|
|
g++ --version
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Install linuxdeploy
|
|
run: script/linux/install_linuxdeploy
|
|
|
|
- name: Load PGP signing key and passphrase
|
|
run: |
|
|
mkdir -p ~/.gnupg
|
|
echo "default-cache-ttl 7200" >> ~/.gnupg/gpg-agent.conf
|
|
|
|
# Set the appropriate permissions for files and directories.
|
|
find ~/.gnupg -type f -exec chmod 600 {} \;
|
|
find ~/.gnupg -type d -exec chmod 700 {} \;
|
|
|
|
# Test the agent configuration. This is helpful for debugging if
|
|
# something is invalid.
|
|
gpgconf --check-options gpg-agent
|
|
gpg-agent --gpgconf-test
|
|
|
|
# Kill the agent, if one is running, and then start a new one - this
|
|
# ensures our updated configuration is applied correctly.
|
|
gpgconf --kill gpg-agent
|
|
gpgconf --launch gpg-agent
|
|
|
|
# Retrieve our signing key and import it into gpg.
|
|
gcloud --project astral-field-294621 secrets versions access latest --secret=linux-releases-pgp-key | gpg --batch --import
|
|
|
|
# Populate the passphrase for our signing key in the gpg-agent cache.
|
|
# by signing an empty file.
|
|
touch emptyfile
|
|
gpg --no-tty --pinentry-mode loopback --passphrase-fd 0 --detach-sign --armor --batch --yes --output emptyfile.sig emptyfile << EOF
|
|
${{ secrets.LINUX_RELEASES_PGP_KEY_PASSPHRASE }}
|
|
EOF
|
|
rm emptyfile.sig
|
|
shell: bash
|
|
|
|
# Namespace's User Bundled Cache persists target/ between jobs on the same profile, which can
|
|
# leave stale packages from a previous channel's build in the linux bundle output dir.
|
|
- name: Clean stale bundle output
|
|
run: rm -rf target/*/bundle/linux
|
|
shell: bash
|
|
|
|
- name: Bundle app
|
|
id: bundle_app
|
|
run: |
|
|
# Build everything but the arch package, as we need to build it
|
|
# within a Docker container.
|
|
script/bundle --channel $CHANNEL --packages appimage,deb,rpm
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Bundle Arch Linux package
|
|
uses: ./.github/actions/bundle_arch_package
|
|
with:
|
|
channel: ${{ steps.get-config.outputs.channel }}
|
|
release-tag: ${{ needs.prepare_release.outputs.release_tag }}
|
|
arch: x86_64
|
|
|
|
- name: Sign Arch Linux packages
|
|
run: |
|
|
./script/linux/sign_arch_packages "$PKGDIR"
|
|
shell: bash
|
|
env:
|
|
PKGDIR: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.debug_executable_path }}
|
|
|
|
- name: Add packages to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
id: upload_github_assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.packages_dir }}/*
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Upload packages to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
# Only upload the files from within `packages_dir`, don't include the
|
|
# (parent) folder itself.
|
|
parent: false
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload packages as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-linux-x86_64-${{ steps.get-config.outputs.channel }}
|
|
path: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
|
|
release_linux_cli_x86:
|
|
name: Build Release (Linux CLI x86_64)
|
|
runs-on: namespace-profile-ubuntu-20-04
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_linux != false }}
|
|
timeout-minutes: 90
|
|
env:
|
|
# Cache the generated settings schema so prepare_bundled_resources only
|
|
# compiles and runs the generator once per job instead of per-package.
|
|
SETTINGS_SCHEMA_CACHE: ${{ github.workspace }}/.settings_schema_cache.json
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: linux
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
# Install gcc 10, as gcc 9.5 has a bug with memcmp that is incompatible
|
|
# with aws-lc-rs (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189).
|
|
- name: Install and configure gcc-10
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install -y gcc-10 g++-10
|
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
|
gcc --version
|
|
g++ --version
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Load PGP signing key and passphrase
|
|
run: |
|
|
mkdir -p ~/.gnupg
|
|
echo "default-cache-ttl 7200" >> ~/.gnupg/gpg-agent.conf
|
|
|
|
# Set the appropriate permissions for files and directories.
|
|
find ~/.gnupg -type f -exec chmod 600 {} \;
|
|
find ~/.gnupg -type d -exec chmod 700 {} \;
|
|
|
|
# Test the agent configuration. This is helpful for debugging if
|
|
# something is invalid.
|
|
gpgconf --check-options gpg-agent
|
|
gpg-agent --gpgconf-test
|
|
|
|
# Kill the agent, if one is running, and then start a new one - this
|
|
# ensures our updated configuration is applied correctly.
|
|
gpgconf --kill gpg-agent
|
|
gpgconf --launch gpg-agent
|
|
|
|
# Retrieve our signing key and import it into gpg.
|
|
gcloud --project astral-field-294621 secrets versions access latest --secret=linux-releases-pgp-key | gpg --batch --import
|
|
|
|
# Populate the passphrase for our signing key in the gpg-agent cache.
|
|
# by signing an empty file.
|
|
touch emptyfile
|
|
gpg --no-tty --pinentry-mode loopback --passphrase-fd 0 --detach-sign --armor --batch --yes --output emptyfile.sig emptyfile << EOF
|
|
${{ secrets.LINUX_RELEASES_PGP_KEY_PASSPHRASE }}
|
|
EOF
|
|
rm emptyfile.sig
|
|
shell: bash
|
|
|
|
# Namespace's User Bundled Cache persists target/ between jobs on the same profile, which can
|
|
# leave stale packages from a previous channel's build in the linux bundle output dir.
|
|
- name: Clean stale bundle output
|
|
run: rm -rf target/*/bundle/linux
|
|
shell: bash
|
|
|
|
- name: Bundle CLI
|
|
id: bundle_cli
|
|
run: |
|
|
# Build CLI only
|
|
script/bundle --channel $CHANNEL --artifact cli --packages deb,rpm
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Package CLI tar.gz
|
|
run: |
|
|
cp ${{ steps.bundle_cli.outputs.executable_path }} oz-${{ steps.get-config.outputs.channel }}
|
|
tar czf oz-${{ steps.get-config.outputs.channel }}-linux-x86_64.tar.gz oz-${{ steps.get-config.outputs.channel }} -C "$(dirname "${{ steps.bundle_cli.outputs.bundled_resources_dir }}")" resources
|
|
|
|
- name: Bundle Arch Linux CLI package
|
|
uses: ./.github/actions/bundle_arch_package
|
|
with:
|
|
channel: ${{ steps.get-config.outputs.channel }}
|
|
release-tag: ${{ needs.prepare_release.outputs.release_tag }}
|
|
arch: x86_64
|
|
artifact: cli
|
|
|
|
- name: Sign Arch Linux packages
|
|
run: |
|
|
./script/linux/sign_arch_packages "$PKGDIR"
|
|
shell: bash
|
|
env:
|
|
PKGDIR: ${{ steps.bundle_cli.outputs.packages_dir }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_cli.outputs.debug_executable_path }}
|
|
|
|
- name: Add CLI packages to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
id: upload_github_assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_cli.outputs.packages_dir }}/*
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Upload CLI packages to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_cli.outputs.packages_dir }}
|
|
# Only upload the files from within `packages_dir`, don't include the
|
|
# (parent) folder itself.
|
|
parent: false
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Add CLI tar.gz to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: oz-${{ steps.get-config.outputs.channel }}-linux-x86_64.tar.gz
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Upload CLI tar.gz to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: oz-${{ steps.get-config.outputs.channel }}-linux-x86_64.tar.gz
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}/cli/linux/x86_64
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload CLI packages as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-linux-cli-x86_64-${{ steps.get-config.outputs.channel }}
|
|
path: |
|
|
${{ steps.bundle_cli.outputs.packages_dir }}
|
|
oz-${{ steps.get-config.outputs.channel }}-linux-x86_64.tar.gz
|
|
|
|
build_linux_arm_binaries:
|
|
name: Build Release (Linux ARM)
|
|
runs-on: namespace-profile-ubuntu-20-04-arm
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_linux != false }}
|
|
timeout-minutes: 90
|
|
env:
|
|
# Automatically extract AppImages before running them instead of mounting
|
|
# them with FUSE, which isn't available on GitHub runners (and this is
|
|
# easier and less error-prone than trying to install it).
|
|
APPIMAGE_EXTRACT_AND_RUN: "1"
|
|
# Cache the generated settings schema so prepare_bundled_resources only
|
|
# compiles and runs the generator once per job instead of per-package.
|
|
SETTINGS_SCHEMA_CACHE: ${{ github.workspace }}/.settings_schema_cache.json
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: linux
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
# Install gcc 10, as gcc 9.5 has a bug with memcmp that is incompatible
|
|
# with aws-lc-rs (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189).
|
|
- name: Install and configure gcc-10
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install -y gcc-10 g++-10
|
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
|
gcc --version
|
|
g++ --version
|
|
|
|
- name: Update path
|
|
run: |
|
|
# Exports .local/bin into the path for subsequent runs.
|
|
# We need this for the linuxdeploy install and bundle steps,
|
|
# as the linuxdeploy appimage is installed to $HOME/local/bin.
|
|
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
|
echo "Adding $HOME/.local/bin to PATH"
|
|
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
fi
|
|
shell: bash
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Install linuxdeploy
|
|
run: script/linux/install_linuxdeploy
|
|
|
|
# Namespace's User Bundled Cache persists target/ between jobs on the same profile, which can
|
|
# leave stale packages from a previous channel's build in the linux bundle output dir.
|
|
- name: Clean stale bundle output
|
|
run: rm -rf target/*/bundle/linux
|
|
shell: bash
|
|
|
|
- name: Build app
|
|
id: build_app
|
|
run: |
|
|
# Build the code, but only bundle the appimage
|
|
script/bundle --channel $CHANNEL --packages appimage
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Package binaries
|
|
id: package_binaries
|
|
run: |
|
|
# Tar up all the binaries we need for the next stage
|
|
EXECUTABLE_PATH="$(realpath --relative-to=$(pwd) $EXECUTABLE_PATH)"
|
|
DEBUG_EXECUTABLE_PATH="$(realpath --relative-to=$(pwd) $DEBUG_EXECUTABLE_PATH)"
|
|
PACKAGES_DIR="$(realpath --relative-to=$(pwd) $PACKAGES_DIR)"
|
|
tar czvf binaries.tar.gz $EXECUTABLE_PATH $DEBUG_EXECUTABLE_PATH $PACKAGES_DIR
|
|
shell: bash
|
|
env:
|
|
EXECUTABLE_PATH: ${{ steps.build_app.outputs.executable_path }}
|
|
DEBUG_EXECUTABLE_PATH: ${{ steps.build_app.outputs.debug_executable_path }}
|
|
PACKAGES_DIR: ${{steps.build_app.outputs.packages_dir}}
|
|
|
|
- name: Archive build files
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: built-arm64-linux-${{steps.get-config.outputs.channel}}
|
|
retention-days: 1
|
|
path: binaries.tar.gz
|
|
|
|
build_linux_cli_arm_binaries:
|
|
name: Build Release (Linux CLI ARM)
|
|
runs-on: namespace-profile-ubuntu-20-04-arm
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_linux != false }}
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: linux
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
# Install gcc 10, as gcc 9.5 has a bug with memcmp that is incompatible
|
|
# with aws-lc-rs (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189).
|
|
- name: Install and configure gcc-10
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install -y gcc-10 g++-10
|
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
|
gcc --version
|
|
g++ --version
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
# Namespace's User Bundled Cache persists target/ between jobs on the same profile, which can
|
|
# leave stale packages from a previous channel's build in the linux bundle output dir.
|
|
- name: Clean stale bundle output
|
|
run: rm -rf target/*/bundle/linux
|
|
shell: bash
|
|
|
|
- name: Build CLI
|
|
id: build_cli
|
|
run: |
|
|
# Build the CLI only
|
|
script/bundle --channel $CHANNEL --artifact cli --packages none
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Package binaries
|
|
id: package_binaries
|
|
run: |
|
|
# Tar up all the binaries we need for the next stage
|
|
EXECUTABLE_PATH="$(realpath --relative-to=$(pwd) $EXECUTABLE_PATH)"
|
|
DEBUG_EXECUTABLE_PATH="$(realpath --relative-to=$(pwd) $DEBUG_EXECUTABLE_PATH)"
|
|
PACKAGES_DIR="$(realpath --relative-to=$(pwd) $PACKAGES_DIR)"
|
|
tar czvf binaries-cli.tar.gz $EXECUTABLE_PATH $DEBUG_EXECUTABLE_PATH $PACKAGES_DIR
|
|
shell: bash
|
|
env:
|
|
EXECUTABLE_PATH: ${{ steps.build_cli.outputs.executable_path }}
|
|
DEBUG_EXECUTABLE_PATH: ${{ steps.build_cli.outputs.debug_executable_path }}
|
|
PACKAGES_DIR: ${{steps.build_cli.outputs.packages_dir}}
|
|
|
|
- name: Archive build files
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: built-arm64-linux-cli-${{steps.get-config.outputs.channel}}
|
|
retention-days: 1
|
|
path: binaries-cli.tar.gz
|
|
|
|
# This is done as a separate job from `build_linux_arm_binaries` and `build_linux_cli_arm_binaries`
|
|
# because the steps here were hard to get running on the self-hosted runners.
|
|
release_linux_arm:
|
|
name: Bundle Release (Linux ARM)
|
|
runs-on: namespace-profile-ubuntu-20-04
|
|
needs: [ prepare_release, build_linux_arm_binaries, build_linux_cli_arm_binaries ]
|
|
if: ${{ inputs.build_linux != false }}
|
|
timeout-minutes: 60
|
|
env:
|
|
# Cache the generated settings schema so prepare_bundled_resources only
|
|
# compiles and runs the generator once per job instead of per-package.
|
|
SETTINGS_SCHEMA_CACHE: ${{ github.workspace }}/.settings_schema_cache.json
|
|
steps:
|
|
- name: Checkout sources
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
# Install gcc 10, as gcc 9.5 has a bug with memcmp that is incompatible
|
|
# with aws-lc-rs (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189).
|
|
- name: Install and configure gcc-10
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install -y gcc-10 g++-10
|
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10
|
|
gcc --version
|
|
g++ --version
|
|
|
|
# Install Linux build dependencies (protoc, libssl-dev, etc.). Although this job
|
|
# runs with --skip-build, script/prepare_bundled_resources still invokes
|
|
# `cargo run --bin generate_settings_schema` and `cargo about generate`, which
|
|
# compile workspace crates whose build scripts depend on protoc and other
|
|
# system libraries. The four sibling Linux jobs get these via prepare_environment;
|
|
# this job doesn't use prepare_environment, so install them explicitly here.
|
|
- name: Install Linux build dependencies
|
|
shell: bash
|
|
run: ./script/linux/install_build_deps
|
|
|
|
- name: Install release dependencies
|
|
shell: bash
|
|
run: |
|
|
./script/install_cargo_release_deps --no-build-deps
|
|
|
|
- name: Load PGP signing key and passphrase
|
|
run: |
|
|
mkdir -p ~/.gnupg
|
|
echo "default-cache-ttl 7200" >> ~/.gnupg/gpg-agent.conf
|
|
|
|
# Set the appropriate permissions for files and directories.
|
|
find ~/.gnupg -type f -exec chmod 600 {} \;
|
|
find ~/.gnupg -type d -exec chmod 700 {} \;
|
|
|
|
# Test the agent configuration. This is helpful for debugging if
|
|
# something is invalid.
|
|
gpgconf --check-options gpg-agent
|
|
gpg-agent --gpgconf-test
|
|
|
|
# Kill the agent, if one is running, and then start a new one - this
|
|
# ensures our updated configuration is applied correctly.
|
|
gpgconf --kill gpg-agent
|
|
gpgconf --launch gpg-agent
|
|
|
|
# Retrieve our signing key and import it into gpg.
|
|
gcloud --project astral-field-294621 secrets versions access latest --secret=linux-releases-pgp-key | gpg --batch --import
|
|
|
|
# Populate the passphrase for our signing key in the gpg-agent cache.
|
|
# by signing an empty file.
|
|
touch emptyfile
|
|
gpg --no-tty --pinentry-mode loopback --passphrase-fd 0 --detach-sign --armor --batch --yes --output emptyfile.sig emptyfile << EOF
|
|
${{ secrets.LINUX_RELEASES_PGP_KEY_PASSPHRASE }}
|
|
EOF
|
|
rm emptyfile.sig
|
|
echo "Populated gpg-agent cache"
|
|
shell: bash
|
|
|
|
# Bundle the app packages
|
|
|
|
# Namespace's User Bundled Cache persists target/ between jobs on the same profile, which can
|
|
# leave stale packages from a previous channel's build in the linux bundle output dir.
|
|
- name: Clean stale bundle output
|
|
run: rm -rf target/*/bundle/linux
|
|
shell: bash
|
|
|
|
- name: Download app build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: built-arm64-linux-${{steps.get-config.outputs.channel}}
|
|
|
|
- name: Unpackage app binaries
|
|
id: unpackage_app_binaries
|
|
run: |
|
|
tar xzvf binaries.tar.gz
|
|
shell: bash
|
|
|
|
- name: Bundle deb/rpm app packages
|
|
id: bundle_app
|
|
run: |
|
|
# Bundle everything but the arch package, as we need to bundle it
|
|
# within a Docker container.
|
|
script/bundle --channel $CHANNEL --skip-build --packages deb,rpm --arch aarch64
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Bundle Arch Linux app package
|
|
uses: ./.github/actions/bundle_arch_package
|
|
with:
|
|
channel: ${{ steps.get-config.outputs.channel }}
|
|
release-tag: ${{ needs.prepare_release.outputs.release_tag }}
|
|
arch: aarch64
|
|
|
|
- name: Upload app debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
# Important: we have to do this before the binary is overwritten by the CLI version, which has the same filename
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.debug_executable_path }}
|
|
shell: bash
|
|
|
|
# Bundle the CLI packages
|
|
|
|
- name: Download CLI build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: built-arm64-linux-cli-${{steps.get-config.outputs.channel}}
|
|
|
|
- name: Unpackage CLI binaries
|
|
id: unpackage_cli_binaries
|
|
run: |
|
|
tar xzvf binaries-cli.tar.gz
|
|
shell: bash
|
|
|
|
- name: Bundle deb/rpm CLI packages
|
|
id: bundle_cli
|
|
run: |
|
|
script/bundle --channel $CHANNEL --skip-build --arch aarch64 --packages deb,rpm --artifact cli
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Package CLI tar.gz
|
|
run: |
|
|
cp ${{ steps.bundle_cli.outputs.executable_path }} oz-${{ steps.get-config.outputs.channel }}
|
|
tar czf oz-${{ steps.get-config.outputs.channel }}-linux-aarch64.tar.gz oz-${{ steps.get-config.outputs.channel }} -C "$(dirname "${{ steps.bundle_cli.outputs.bundled_resources_dir }}")" resources
|
|
|
|
- name: Bundle Arch Linux CLI package
|
|
uses: ./.github/actions/bundle_arch_package
|
|
with:
|
|
channel: ${{ steps.get-config.outputs.channel }}
|
|
release-tag: ${{ needs.prepare_release.outputs.release_tag }}
|
|
arch: aarch64
|
|
artifact: cli
|
|
|
|
- name: Upload CLI debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_cli.outputs.debug_executable_path }}
|
|
shell: bash
|
|
|
|
# Common uploading steps
|
|
|
|
- name: Sign Arch Linux packages
|
|
run: |
|
|
# We technically only need to run `sign_arch_packages` once, as $APP_PKGDIR and $CLI_PKGDIR should be the same.
|
|
./script/linux/sign_arch_packages "$APP_PKGDIR"
|
|
./script/linux/sign_arch_packages "$CLI_PKGDIR"
|
|
shell: bash
|
|
env:
|
|
APP_PKGDIR: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
CLI_PKGDIR: ${{ steps.bundle_cli.outputs.packages_dir }}
|
|
|
|
- name: Add app packages to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.packages_dir }}/*
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Add CLI packages to GitHub release assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' && steps.bundle_cli.outputs.packages_dir != steps.bundle_app.outputs.packages_dir }}
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_cli.outputs.packages_dir }}/*
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Add CLI tar.gz to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: oz-${{ steps.get-config.outputs.channel }}-linux-aarch64.tar.gz
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Upload app packages to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
parent: false
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload CLI packages to Google Cloud Storage
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' && steps.bundle_cli.outputs.packages_dir != steps.bundle_app.outputs.packages_dir }}
|
|
with:
|
|
path: ${{ steps.bundle_cli.outputs.packages_dir }}
|
|
parent: false
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload CLI tar.gz to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: oz-${{ steps.get-config.outputs.channel }}-linux-aarch64.tar.gz
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}/cli/linux/aarch64
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload packages as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-linux-arm64-${{ steps.get-config.outputs.channel }}
|
|
path: |
|
|
${{ steps.bundle_app.outputs.packages_dir }}
|
|
oz-${{ steps.get-config.outputs.channel }}-linux-aarch64.tar.gz
|
|
|
|
release_web:
|
|
name: Build Release (Web)
|
|
runs-on: namespace-profile-ubuntu-22-04
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_web != false }}
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: wasm
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Bundle app
|
|
id: bundle_app
|
|
run: |
|
|
script/wasm/bundle --channel $CHANNEL
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Brotli compress app bundle
|
|
run: |
|
|
# The brotli binary won't let us compress in-place, so we need to rename back to the
|
|
# original afterwards.
|
|
brotli --rm "${{ steps.bundle_app.outputs.packages_dir }}"/*
|
|
for file in "${{ steps.bundle_app.outputs.packages_dir }}"/*.br; do
|
|
mv -- "$file" "${file%.br}"
|
|
done
|
|
shell: bash
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.debug_executable_path }}
|
|
|
|
- name: Add packages to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
id: upload_github_assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.packages_dir }}/*
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload packages to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
# Only upload the files from within `packages_dir`, don't include the
|
|
# (parent) folder itself.
|
|
gzip: false
|
|
parent: false
|
|
destination: ${{ steps.get-config.outputs.web_gcs_bucket_prefix }}-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
content-encoding: br
|
|
|
|
- name: Upload assets to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.assets_dir }}
|
|
parent: false
|
|
# All asset filenames contain the file hash for cashing purposes, so we store them all in
|
|
# one directory so they can be cached across releases.
|
|
destination: ${{ steps.get-config.outputs.web_gcs_bucket_prefix }}-static-assets/
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
# These assets are all stored under cache busting names, so we want to cache them
|
|
# effectively forever. There's no defined maximum for the max-age directive, but a similar
|
|
# directive suggests a maximum of one year, so that's what's chosen here.
|
|
headers: |-
|
|
cache-control: private, max-age=31536000, immutable
|
|
|
|
- name: Upload web bundle as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-web-${{ steps.get-config.outputs.channel }}
|
|
path: ${{ steps.bundle_app.outputs.packages_dir }}
|
|
|
|
release_windows:
|
|
name: Build Release (Windows ${{ matrix.arch }})
|
|
runs-on: ${{ matrix.runner }}
|
|
needs: prepare_release
|
|
if: ${{ inputs.build_windows != false }}
|
|
timeout-minutes: 150
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- arch: x64
|
|
runner: windows-latest-large
|
|
- arch: arm64
|
|
runner: windows-latest-large
|
|
env:
|
|
TRUSTED_SIGNING_ENDPOINT: https://eus.codesigning.azure.net/
|
|
TRUSTED_SIGNING_ACCOUNT: warpdotdev
|
|
TRUSTED_SIGNING_CERT_PROFILE: warpterminal
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- uses: ./.github/actions/prepare_environment
|
|
with:
|
|
target_os: windows
|
|
cache_key: ${{ matrix.arch }}
|
|
is_self_hosted: false
|
|
ref: ${{ needs.prepare_release.outputs.release_branch }}
|
|
install_release_deps: true
|
|
ssh_key: ${{ secrets.WARP_CHANNEL_CONFIG_ACCESS_SSH_KEY }}
|
|
|
|
- name: Add arm64 target
|
|
if: ${{ matrix.arch == 'arm64' }}
|
|
run: rustup target add aarch64-pc-windows-msvc
|
|
shell: bash
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
- name: Build binary
|
|
id: build_binary
|
|
run: script/bundle -Channel $CHANNEL -skip_build_installer --arch ${{ matrix.arch }}
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Sign the executables with Azure Trusted Signing
|
|
uses: azure/artifact-signing-action@b443cf8ea4124818d2ea9f043cba29fc3ec47b16 # v1.2.0
|
|
with:
|
|
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
|
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
|
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
|
endpoint: ${{ env.TRUSTED_SIGNING_ENDPOINT }}
|
|
trusted-signing-account-name: ${{ env.TRUSTED_SIGNING_ACCOUNT }}
|
|
certificate-profile-name: ${{ env.TRUSTED_SIGNING_CERT_PROFILE }}
|
|
files: |
|
|
${{ steps.build_binary.outputs.binary_path }}
|
|
${{ github.workspace }}\app\assets\bundled\bootstrap\pwsh.ps1
|
|
files-folder: ${{ github.workspace }}\app\assets\windows\${{ matrix.arch }}
|
|
files-folder-filter: dll,exe
|
|
files-folder-recurse: true
|
|
files-folder-depth: 2
|
|
file-digest: SHA256
|
|
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
|
timestamp-digest: SHA256
|
|
|
|
# The azure/artifact-signing-action above downloads signtool.exe and the Trusted Signing dlib.
|
|
# We locate them so ISCC can call signtool during compilation to sign the inner setup engine
|
|
# (the file extracted to %TEMP% at runtime). This prevents Defender ASR rule D4F940AB from
|
|
# blocking the installer in enterprise environments. See this issue:
|
|
# https://github.com/warpdotdev/Warp/issues/8794
|
|
- name: Build sign-tool command for Inno Setup
|
|
id: setup_signing
|
|
shell: pwsh
|
|
run: |
|
|
$Dlib = (Get-ChildItem -Recurse "$env:LOCALAPPDATA" -Filter "Azure.CodeSigning.Dlib.dll" -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -match 'x64' } | Select-Object -First 1).FullName
|
|
if (-not $Dlib) { throw "Azure.CodeSigning.Dlib.dll not found — did the earlier signing action run?" }
|
|
Write-Output "Dlib: $Dlib"
|
|
$SignTool = (Get-ChildItem -Recurse "C:\Program Files (x86)\Windows Kits" -Filter "signtool.exe" |
|
|
Where-Object { $_.FullName -match 'x64' } | Sort-Object FullName -Descending | Select-Object -First 1).FullName
|
|
if (-not $SignTool) { throw "signtool.exe not found in Windows SDK" }
|
|
Write-Output "SignTool: $SignTool"
|
|
# Add signtool's directory to PATH so the ISCC sign command can reference it as just "signtool.exe".
|
|
# Embedded quotes in the /Scodesign= value break PowerShell's native-command argument passing to ISCC.
|
|
(Split-Path $SignTool) >> $env:GITHUB_PATH
|
|
$MetadataPath = "${{ runner.temp }}\tsc-metadata.json"
|
|
@{Endpoint=$env:TRUSTED_SIGNING_ENDPOINT;CodeSigningAccountName=$env:TRUSTED_SIGNING_ACCOUNT;CertificateProfileName=$env:TRUSTED_SIGNING_CERT_PROFILE} |
|
|
ConvertTo-Json | Set-Content $MetadataPath
|
|
"sign_tool_cmd=signtool.exe sign /v /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 /dlib $Dlib /dmdf $MetadataPath `$f" >> $env:GITHUB_OUTPUT
|
|
|
|
- name: Bundle app
|
|
id: bundle_app
|
|
run: script/bundle -Channel $CHANNEL -skip_build_binary --arch ${{ matrix.arch }}
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ steps.get-config.outputs.channel }}
|
|
GIT_RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
|
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
|
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
|
SIGN_TOOL_CMD: ${{ steps.setup_signing.outputs.sign_tool_cmd }}
|
|
|
|
- name: Set up Sentry CLI
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2.0.0
|
|
with:
|
|
token: ${{ secrets.SENTRY_RELEASE_TOKEN }}
|
|
organization: warpdotdev
|
|
project: ${{ steps.get-config.outputs.sentry_project }}
|
|
|
|
- name: Upload binary to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.build_binary.outputs.binary_path }}
|
|
|
|
- name: Upload debugging symbols to Sentry
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
run: |
|
|
script/sentry_upload_dif.sh
|
|
shell: bash
|
|
env:
|
|
DEBUG_FILE_OR_FOLDER_PATH: ${{ steps.bundle_app.outputs.pdb_file_path }}
|
|
|
|
- name: Add installer to GitHub release assets
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
id: upload_github_assets
|
|
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
with:
|
|
tag_name: ${{ needs.prepare_release.outputs.release_tag }}
|
|
files: ${{ steps.bundle_app.outputs.installer_path }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload installer to Google Cloud Storage
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: ${{ steps.bundle_app.outputs.installer_path }}
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|
|
# IMPORTANT: both the key and value of the cache-control header must be all lowercase;
|
|
# uppercase values will not be respected by Cloud CDN and using "Cache-Control" will be
|
|
# ignored by the upload-cloud-storage action.
|
|
headers: |-
|
|
cache-control: ${{ steps.get-config.outputs.gcs_cache_control_value }}
|
|
|
|
- name: Upload installer as workflow artifact
|
|
if: ${{ needs.prepare_release.outputs.should_publish != 'true' }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: release-windows-${{ matrix.arch }}-${{ steps.get-config.outputs.channel }}
|
|
path: ${{ steps.bundle_app.outputs.installer_path }}
|
|
|
|
send_slack_notif_if_unsuccessful:
|
|
name: Send Slack notification if any release jobs were unsuccessful
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- prepare_release
|
|
- release_macos_single_arch
|
|
- release_macos_universal
|
|
- release_macos_cli
|
|
- release_linux_x86
|
|
- release_linux_arm
|
|
- release_linux_cli_x86
|
|
- release_web
|
|
- release_windows
|
|
if: ${{ always() && needs.prepare_release.outputs.should_publish == 'true' }}
|
|
steps:
|
|
- name: Figure out which releases failed, if any
|
|
id: failed_releases
|
|
shell: bash
|
|
run: |
|
|
FAILED=()
|
|
if [[ ${{ needs.release_macos_single_arch.result }} != 'success' ]]; then
|
|
FAILED+=("MacOS Single Arch")
|
|
fi
|
|
if [[ ${{ needs.release_macos_universal.result }} != 'success' ]]; then
|
|
FAILED+=("MacOS Universal")
|
|
fi
|
|
if [[ ${{ needs.release_macos_cli.result }} != 'success' ]]; then
|
|
FAILED+=('MacOS CLI')
|
|
fi
|
|
if [[ ${{ needs.release_linux_x86.result }} != 'success' ]]; then
|
|
FAILED+=("Linux x86_64")
|
|
fi
|
|
if [[ ${{ needs.release_linux_arm.result }} != 'success' ]]; then
|
|
FAILED+=("Linux ARM64")
|
|
fi
|
|
if [[ ${{ needs.release_linux_cli_x86.result }} != 'success' ]]; then
|
|
FAILED+=("Linux CLI x86_64")
|
|
fi
|
|
if [[ ${{ needs.release_web.result }} != 'success' && ${{ inputs.channel }} != 'preview' ]]; then
|
|
FAILED+=("WASM")
|
|
fi
|
|
if [[ ${{ needs.release_windows.result }} != 'success' ]]; then
|
|
FAILED+=("Windows")
|
|
fi
|
|
|
|
if (( ${#FAILED[@]} )); then
|
|
printf -v FORMATTED "%s, " "${FAILED[@]}"
|
|
echo "failed=$(echo "{${FORMATTED%, }}")" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Send Slack notification if unsuccessful
|
|
uses: slackapi/slack-github-action@410ae57cff5c6b682b106440be0e6c7eb8c98c9d # v1.16.0
|
|
if: ${{ steps.failed_releases.outputs.failed != '' }}
|
|
with:
|
|
channel-id: "#oncall-client"
|
|
# Follows https://api.slack.com/reference/surfaces/formatting#mentioning-users.
|
|
# S06N82RS7FA is the user group ID for @oncall-client-eng.
|
|
slack-message: "Failed to create ${{ steps.failed_releases.outputs.failed }} release artifacts for ${{ inputs.channel }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}. cc: <!subteam^S06N82RS7FA>"
|
|
env:
|
|
SLACK_BOT_TOKEN: ${{ secrets.ACTION_MONITORING_SLACK }}
|
|
|
|
generate_changelogs:
|
|
name: Generate Changelogs
|
|
if: ${{ needs.prepare_release.outputs.should_publish == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- prepare_release
|
|
- release_macos_single_arch
|
|
- release_macos_universal
|
|
- release_macos_cli
|
|
- release_linux_x86
|
|
- release_linux_arm
|
|
- release_linux_cli_x86
|
|
- release_web
|
|
- release_windows
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
name: Checkout sources
|
|
with:
|
|
# Fetch history for all tags and branches so we can compare revisions
|
|
# in order to generate the changelog.
|
|
fetch-depth: 0
|
|
|
|
- name: Get channel configuration
|
|
id: get-config
|
|
uses: ./.github/actions/get_channel_config/
|
|
with:
|
|
config_file: ${{ env.CONFIG_FILE }}
|
|
channel: ${{ inputs.channel }}
|
|
|
|
# Stable releases use the Oz changelog-draft agent for higher-quality,
|
|
# human-reviewable output. Non-stable channels (dev/preview/beta) use the
|
|
# legacy generate-changelog action to avoid spending Oz agent tokens on
|
|
# daily dev cuts and preview RCs.
|
|
- name: Generate changelog via Oz (stable only)
|
|
if: inputs.channel == 'stable'
|
|
uses: warpdotdev/oz-agent-action@ce1621abf6a8ed8afdd4e4cc994545ede8fe1c6f # main
|
|
with:
|
|
prompt: |
|
|
Generate a changelog draft for the ${{ inputs.channel }} channel, release tag ${{ needs.prepare_release.outputs.release_tag }}.
|
|
|
|
Output directory: ${{ runner.temp }}/changelog-draft
|
|
|
|
Follow the workflow in .agents/skills/changelog-draft/SKILL.md exactly.
|
|
Make sure to produce both output files: changelog-draft.md and changelog-draft.json.
|
|
The release workflow may run from warpdotdev/warp-internal. When fetching PR data, pass the checked-out repository ("${{ github.repository }}") to fetch_prs.py and rely on the script's repo-sync normalization to resolve public warpdotdev/warp PR numbers, URLs, and authors. The script intentionally omits non-repo-sync PRs from warp-internal because they are private internal changes. Do not infer or synthesize public PR links manually.
|
|
|
|
After writing the output files, print the full contents of changelog-draft.md to stdout so it appears in the workflow log.
|
|
|
|
You are running in a GitHub Actions workflow. The repo is checked out at the default branch (HEAD) with full history. Use the release_tag input as the git range endpoint — do NOT check out the release tag. `gh` is authenticated. Do not commit, push, or create PRs.
|
|
warp_api_key: ${{ secrets.WARP_API_KEY }}
|
|
share: team
|
|
- name: Upload raw Markdown changelog artifact (stable only)
|
|
if: inputs.channel == 'stable'
|
|
id: upload_changelog_draft_markdown
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: changelog-draft-markdown
|
|
path: ${{ runner.temp }}/changelog-draft/changelog-draft.md
|
|
if-no-files-found: error
|
|
|
|
- name: Convert draft JSON to release format (stable only)
|
|
if: inputs.channel == 'stable'
|
|
shell: bash
|
|
run: |
|
|
python3 .agents/skills/changelog-draft/scripts/convert_to_release_json.py \
|
|
--input "${{ runner.temp }}/changelog-draft/changelog-draft.json" \
|
|
--output "${{ runner.temp }}/changelog-draft/changelog-release.json"
|
|
|
|
- name: Obtain a GitHub App Installation Access Token (non-stable only)
|
|
if: inputs.channel != 'stable'
|
|
id: github_app_auth
|
|
run: |
|
|
TOKEN="$(npx obtain-github-app-installation-access-token ci ${{ secrets.GH_APP_CREDENTIALS_TOKEN }})"
|
|
echo "::add-mask::$TOKEN"
|
|
echo "token=$TOKEN" >> $GITHUB_OUTPUT
|
|
|
|
- name: Generate changelog via legacy action (non-stable only)
|
|
if: inputs.channel != 'stable'
|
|
id: legacy_changelog
|
|
uses: warpdotdev/generate-changelog@70f534c1e030dafb45046ae57e4aa4d43a2f5c84 # main
|
|
with:
|
|
channel: ${{ inputs.channel }}
|
|
github_auth_token: ${{ steps.github_app_auth.outputs.token }}
|
|
version: ${{ needs.prepare_release.outputs.release_tag }}
|
|
|
|
- name: Load changelog into step output
|
|
id: generate_changelog
|
|
shell: bash
|
|
env:
|
|
LEGACY_CHANGELOG: ${{ steps.legacy_changelog.outputs.changelog }}
|
|
run: |
|
|
# Bridge step: picks whichever generator ran for this channel and
|
|
# re-emits the changelog as outputs.changelog so downstream Slack/GCS
|
|
# steps work unchanged.
|
|
if [[ "${{ inputs.channel }}" == "stable" ]]; then
|
|
CHANGELOG_FILE="${{ runner.temp }}/changelog-draft/changelog-release.json"
|
|
if [ ! -f "$CHANGELOG_FILE" ]; then
|
|
echo "::error::changelog-release.json not found at $CHANGELOG_FILE"
|
|
exit 1
|
|
fi
|
|
jq empty "$CHANGELOG_FILE"
|
|
{
|
|
echo "changelog<<CHANGELOG_EOF"
|
|
cat "$CHANGELOG_FILE"
|
|
echo "CHANGELOG_EOF"
|
|
} >> $GITHUB_OUTPUT
|
|
else
|
|
echo "$LEGACY_CHANGELOG" | jq empty
|
|
{
|
|
echo "changelog<<CHANGELOG_EOF"
|
|
printf '%s\n' "$LEGACY_CHANGELOG"
|
|
echo "CHANGELOG_EOF"
|
|
} >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Build Slack changelog payload
|
|
id: build_slack_payload
|
|
shell: bash
|
|
env:
|
|
CHANGELOG_JSON: ${{ steps.generate_changelog.outputs.changelog }}
|
|
RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
|
|
MARKDOWN_ARTIFACT_URL: ${{ steps.upload_changelog_draft_markdown.outputs.artifact-url }}
|
|
run: |
|
|
CHANGELOG_INPUT="${{ runner.temp }}/slack-changelog-input.json"
|
|
SLACK_PAYLOAD="${{ runner.temp }}/slack-changelog-payload.json"
|
|
printf '%s\n' "$CHANGELOG_JSON" > "$CHANGELOG_INPUT"
|
|
python3 .agents/skills/changelog-draft/scripts/build_slack_payload.py \
|
|
--input "$CHANGELOG_INPUT" \
|
|
--release-tag "$RELEASE_TAG" \
|
|
--markdown-artifact-url "$MARKDOWN_ARTIFACT_URL" \
|
|
--output "$SLACK_PAYLOAD"
|
|
if ! jq -e '.blocks | length > 0' "$SLACK_PAYLOAD" >/dev/null; then
|
|
echo "has_content=" >> $GITHUB_OUTPUT
|
|
exit 0
|
|
fi
|
|
echo "has_content=true" >> $GITHUB_OUTPUT
|
|
|
|
echo "payload<<SLACK_PAYLOAD_EOF" >> $GITHUB_OUTPUT
|
|
cat "$SLACK_PAYLOAD" >> $GITHUB_OUTPUT
|
|
echo "SLACK_PAYLOAD_EOF" >> $GITHUB_OUTPUT
|
|
|
|
- name: Post to a Slack channel
|
|
id: slack
|
|
uses: slackapi/slack-github-action@410ae57cff5c6b682b106440be0e6c7eb8c98c9d # v1.16.0
|
|
if: ${{ steps.build_slack_payload.outputs.has_content == 'true' }}
|
|
# Continue on with the rest of the workflow, even if we fail to send the
|
|
# changelog info to Slack. (We still want to stick the changelog JSON
|
|
# in Cloud Storage.)
|
|
continue-on-error: true
|
|
with:
|
|
channel-id: ${{ steps.get-config.outputs.changelog_slack_channel }}
|
|
payload: ${{ steps.build_slack_payload.outputs.payload }}
|
|
env:
|
|
SLACK_BOT_TOKEN: ${{ secrets.SLACK_CHANGELOG_BOT }}
|
|
|
|
- name: Generate changelog.json
|
|
id: changelog_json
|
|
env:
|
|
CHANGELOG: ${{ steps.generate_changelog.outputs.changelog }}
|
|
run: |
|
|
# Compute the current date/time in the necessary format.
|
|
DATE=$(date +%Y-%m-%dT%k:%M:%S%z)
|
|
# Rename the "newFeatures" and "improvements" keys in the Changelog JSON to something more human readable
|
|
# and ignore everything else since this is for the in-app changelog.
|
|
CHANGELOG_SECTIONS=$(echo $CHANGELOG | jq 'with_entries(select(.key == "newFeatures" or .key == "improvements"))' | jq 'with_entries(if .key == "newFeatures" then .key = "New features" else . end)' | jq 'with_entries(if .key == "improvements" then .key = "Improvements" else . end)')
|
|
# create markdown strings for the New Features and Improvements sections
|
|
NEW_FEATURES=$(echo $CHANGELOG_SECTIONS | jq 'with_entries(select(.key == "New features"))' | jq -r 'to_entries[] | "* \(.value[])"' | awk -v ORS='\n' '1')
|
|
IMPROVEMENTS=$(echo $CHANGELOG_SECTIONS | jq 'with_entries(select(.key == "Improvements"))' | jq -r 'to_entries[] | "* \(.value[])"' | awk -v ORS='\n' '1')
|
|
# Extract the image URL from the list, and use the latest URL even if there are multiple
|
|
IMAGE=$(echo $CHANGELOG | jq -r '.images | if length > 0 then .[-1] else "" end')
|
|
# Extract Oz updates as a JSON array
|
|
OZ_UPDATES=$(echo $CHANGELOG | jq -c '.oz_updates // []')
|
|
# Tweak the structure of the JSON, add in a top-level date field, and add in the markdown_sections field
|
|
CHANGELOG=$(echo $CHANGELOG_SECTIONS | jq --arg date "$DATE" --arg new_features "$NEW_FEATURES" --arg improvements "$IMPROVEMENTS" --arg image "$IMAGE" --argjson oz_updates "$OZ_UPDATES" '{"date": $date, "sections": to_entries | map({"title": .key, "items": .value}), "markdown_sections": [{"title": "New features", "markdown": $new_features}, {"title": "Improvements", "markdown": $improvements}, {"title": "Coming soon", "markdown": ""}]} + (if $image != "" then {"image_url": $image} else {} end) + (if ($oz_updates | length) > 0 then {"oz_updates": $oz_updates} else {} end)')
|
|
|
|
echo $CHANGELOG > changelog.json
|
|
cat changelog.json
|
|
shell: bash
|
|
|
|
- uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
|
|
with:
|
|
credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
|
|
- name: Upload changelog.json to Google Cloud Storage
|
|
uses: google-github-actions/upload-cloud-storage@e95a15f226403ed658d3e65f40205649f342ba2c # v1
|
|
with:
|
|
path: changelog.json
|
|
destination: warp-releases/${{ steps.get-config.outputs.channel }}/${{ needs.prepare_release.outputs.release_tag }}
|