Skip to content

Build and Release

Build and Release #237

Workflow file for this run

name: Build and Release
on:
push:
tags:
- "v*.*.*" # validated by set-metadata
schedule:
- cron: "0 4 * * *"
workflow_dispatch:
inputs:
build_type:
description: "Build type"
required: false
type: choice
options:
- nightly
- production
- beta
default: nightly
platforms:
description: "Platforms to build ('all', or 'macos,linux,android,ios,windows')"
required: false
type: string
default: "linux"
linux_arch:
description: "Linux arch to build when Linux is included"
required: false
type: choice
options:
- all
- amd64
- arm64
default: all
cleanup_on_failure:
description: "Delete draft release on failure"
required: false
type: boolean
default: true
permissions:
contents: write
id-token: "write"
concurrency:
group: ${{ github.ref }}
cancel-in-progress: false
jobs:
set-metadata:
# Allow tag-push releases, scheduled builds from default branch,
# and workflow_dispatch from any branch (non-main branches create
# draft releases that are immediately deleted for testing).
if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'schedule' && github.ref_name == github.event.repository.default_branch) || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
outputs:
build_type: ${{ steps.meta.outputs.build_type }}
release_tag: ${{ steps.meta.outputs.release_tag }}
version: ${{ steps.meta.outputs.version }}
installer_base_name: ${{ steps.meta.outputs.installer_base_name }}
platform: ${{ steps.meta.outputs.platform }}
linux_arch: ${{ steps.meta.outputs.linux_arch }}
is_test_run: ${{ steps.meta.outputs.is_test_run }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
fetch-tags: true
- id: meta
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
EVENT="${{ github.event_name }}"
case "$EVENT" in
schedule)
# Scheduled nightly build
BUILD_TYPE="nightly"
VERSION=$(./scripts/ci/version.sh generate nightly)
RELEASE_TAG="v${VERSION}"
PLATFORM="all"
LINUX_ARCH="all"
;;
workflow_dispatch)
# Manual trigger
BUILD_TYPE="${{ github.event.inputs.build_type }}"
PLATFORM="${{ github.event.inputs.platforms }}"
LINUX_ARCH="${{ github.event.inputs.linux_arch }}"
case "$BUILD_TYPE" in
nightly|beta)
VERSION=$(./scripts/ci/version.sh generate "$BUILD_TYPE")
RELEASE_TAG="v${VERSION}"
;;
production)
echo "Error: Production builds must use git tags, not manual dispatch" >&2
exit 1
;;
esac
;;
push)
# Tag push (release build) - preserve original tag with 'v' prefix
RELEASE_TAG=${GITHUB_REF#refs/tags/}
# Validate the tag (version.sh strips 'v' for validation)
./scripts/ci/version.sh validate "$RELEASE_TAG" > /dev/null
# Strip 'v' for VERSION (used by build workflows)
VERSION="${RELEASE_TAG#v}"
case "$RELEASE_TAG" in
*-beta*)
BUILD_TYPE="beta"
;;
*)
# Production: bare version or version with platform suffix
# e.g., v9.0.15 (all platforms) or v9.0.15-android (single platform)
if [[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(windows|macos|linux|android|ios))?$ ]]; then
BUILD_TYPE="production"
else
echo "Error: Invalid tag format for build" >&2
echo " Use 'v1.0.0' for production (all platforms)" >&2
echo " Use 'v1.0.0-<platform>' for production (single platform)" >&2
echo " Use 'v1.0.0-beta' for beta" >&2
echo "Got: $RELEASE_TAG" >&2
exit 1
fi
;;
esac
# Extract platform suffix (if any)
platform_suffix="${RELEASE_TAG##*-}"
case "$platform_suffix" in
windows) PLATFORM="windows" ;;
macos) PLATFORM="macos" ;;
linux) PLATFORM="linux" ;;
android) PLATFORM="android" ;;
ios) PLATFORM="ios" ;;
*) PLATFORM="all" ;;
esac
# Strip platform suffix from VERSION (platform is tracked separately)
case "$PLATFORM" in
all) ;;
*) VERSION="${VERSION%-$PLATFORM}" ;;
esac
case "$PLATFORM" in
all|linux) LINUX_ARCH="all" ;;
*) LINUX_ARCH="amd64" ;;
esac
;;
esac
case "$LINUX_ARCH" in
all|amd64|arm64) ;;
*)
echo "Error: Invalid linux_arch '$LINUX_ARCH' (expected: all, amd64, arm64)" >&2
exit 1
;;
esac
# Installer base name - Makefile will append build type
INSTALLER_BASE_NAME="lantern-installer"
echo "Build Configuration:"
echo " Event: $EVENT"
echo " Build Type: $BUILD_TYPE"
echo " Release Tag: $RELEASE_TAG"
echo " Version: $VERSION"
echo " Platform: $PLATFORM"
echo " Linux Arch: $LINUX_ARCH"
echo " Installer: $INSTALLER_BASE_NAME"
# Test run: workflow_dispatch from non-default branch
IS_TEST_RUN="false"
if [[ "$EVENT" == "workflow_dispatch" ]]; then
DEFAULT_BRANCH="${{ github.event.repository.default_branch }}"
if [[ "${{ github.ref_name }}" != "$DEFAULT_BRANCH" ]]; then
IS_TEST_RUN="true"
echo "Test run: draft release will be deleted after build"
fi
fi
echo "build_type=$BUILD_TYPE" >> $GITHUB_OUTPUT
echo "release_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "platform=$PLATFORM" >> $GITHUB_OUTPUT
echo "linux_arch=$LINUX_ARCH" >> $GITHUB_OUTPUT
echo "installer_base_name=$INSTALLER_BASE_NAME" >> $GITHUB_OUTPUT
echo "is_test_run=$IS_TEST_RUN" >> $GITHUB_OUTPUT
- name: Update pubspec.yaml version
shell: bash
env:
RELEASE_TAG: ${{ steps.meta.outputs.release_tag }}
run: |
# Strip 'v' prefix if present
VERSION="${RELEASE_TAG#v}"
# Extract base semver (strip suffixes like -beta, -nightly-...)
BASE_VERSION=$(./scripts/ci/version.sh extract "$VERSION")
CURRENT_BUILD=$(grep '^version:' pubspec.yaml | sed -E 's/^version: [0-9]+\.[0-9]+\.[0-9]+\+([0-9]+).*/\1/')
BUILD_NUMBER=$((CURRENT_BUILD + 1))
FULL_VERSION="${BASE_VERSION}+${BUILD_NUMBER}"
echo "Setting pubspec version: $FULL_VERSION"
echo " Base version: $BASE_VERSION"
echo " Build number: $BUILD_NUMBER"
sed -i.bak -E "s/^version:.*/version: ${FULL_VERSION}/" pubspec.yaml
grep '^version:' pubspec.yaml
- name: Upload pubspec.yaml
uses: actions/upload-artifact@v4
with:
name: pubspec
path: pubspec.yaml
release-notify:
needs: [set-metadata]
if: |
needs.set-metadata.outputs.build_type == 'production' &&
needs.set-metadata.outputs.platform == 'all'
runs-on: ubuntu-latest
steps:
- name: Notify Slack
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
{
"text": "Production release v${{ needs.set-metadata.outputs.version }} awaiting approval before releasing on all platforms: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
release-approval:
needs: [set-metadata]
if: |
needs.set-metadata.outputs.build_type == 'production' &&
needs.set-metadata.outputs.platform == 'all'
runs-on: ubuntu-latest
environment: production
steps:
- run: echo "Approved"
build-macos:
needs: [set-metadata, release-create, release-approval]
uses: ./.github/workflows/build-macos.yml
secrets: inherit
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.release-create.result == 'success' &&
(needs.release-approval.result == 'success' || needs.release-approval.result == 'skipped') &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'macos'))
with:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
build-windows:
needs: [set-metadata, release-create, release-approval]
uses: ./.github/workflows/build-windows.yml
secrets: inherit
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.release-create.result == 'success' &&
(needs.release-approval.result == 'success' || needs.release-approval.result == 'skipped') &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'windows'))
with:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
enable_ip_check: ${{ needs.set-metadata.outputs.build_type == 'nightly' }}
build-linux:
needs: [set-metadata, release-create, release-approval]
uses: ./.github/workflows/build-linux.yml
secrets: inherit
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.release-create.result == 'success' &&
(needs.release-approval.result == 'success' || needs.release-approval.result == 'skipped') &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'linux'))
with:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
linux_arch: ${{ needs.set-metadata.outputs.linux_arch }}
build-ios:
needs: [set-metadata, release-create, release-approval]
uses: ./.github/workflows/build-ios.yml
secrets: inherit
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.release-create.result == 'success' &&
(needs.release-approval.result == 'success' || needs.release-approval.result == 'skipped') &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'ios'))
with:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
build-android:
needs: [set-metadata, release-create, release-approval]
uses: ./.github/workflows/build-android.yml
secrets: inherit
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.release-create.result == 'success' &&
(needs.release-approval.result == 'success' || needs.release-approval.result == 'skipped') &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'android'))
with:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
release-create:
needs: set-metadata
runs-on: ubuntu-latest
env:
BUILD_TYPE: ${{ needs.set-metadata.outputs.build_type }}
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
# Strip 'v' prefix for display
VERSION="${RELEASE_TAG#v}"
case "$BUILD_TYPE" in
production)
PRERELEASE_FLAG=""
TITLE="Lantern $VERSION"
;;
beta)
PRERELEASE_FLAG="--prerelease"
TITLE="Beta $VERSION"
;;
nightly)
PRERELEASE_FLAG="--prerelease"
TITLE="Nightly $VERSION"
;;
esac
WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
gh release create "$RELEASE_TAG" \
--draft \
$PRERELEASE_FLAG \
--title "$TITLE" \
--notes "Build [in progress](${WORKFLOW_URL})..."
upload-s3:
needs:
[
set-metadata,
build-macos,
build-windows,
build-linux,
build-android,
build-ios,
]
if: |
!cancelled() &&
(needs.build-macos.result == 'success' || needs.build-macos.result == 'skipped') &&
(needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped') &&
(needs.build-linux.result == 'success' || needs.build-linux.result == 'skipped') &&
(needs.build-android.result == 'success' || needs.build-android.result == 'skipped') &&
(needs.build-ios.result == 'success' || needs.build-ios.result == 'skipped') &&
(needs.build-macos.result == 'success' || needs.build-windows.result == 'success' ||
needs.build-linux.result == 'success' || needs.build-android.result == 'success' ||
needs.build-ios.result == 'success')
runs-on: ubuntu-latest
env:
BUILD_TYPE: ${{ needs.set-metadata.outputs.build_type }}
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
INSTALLER_BASE_NAME: ${{ needs.set-metadata.outputs.installer_base_name }}
PLATFORM: ${{ needs.set-metadata.outputs.platform }}
LINUX_ARCH: ${{ needs.set-metadata.outputs.linux_arch }}
BUCKET: ${{ vars.S3_RELEASES_BUCKET }}
GITHUB_REF_NAME: ${{ github.ref_name }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Download build artifacts
uses: actions/download-artifact@v4
- name: Upload to S3
shell: bash
run: |
# Strip 'v' prefix for S3 paths
VERSION="${RELEASE_TAG#v}"
./scripts/ci/publish-to-s3.sh \
"$BUILD_TYPE" \
"$VERSION" \
"$INSTALLER_BASE_NAME" \
"$PLATFORM"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Format GitHub job summary
shell: bash
run: ./scripts/ci/format.sh job-summary >> "$GITHUB_STEP_SUMMARY"
env:
RELEASE_TAG: ${{ env.RELEASE_TAG }}
- name: Format Slack message
id: slack_msg
env:
RELEASE_TAG: ${{ env.RELEASE_TAG }}
run: |
text=$(./scripts/ci/format.sh slack)
echo "text<<EOF" >> "$GITHUB_OUTPUT"
echo "$text" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Notify Slack
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
{
"text": "${{ steps.slack_msg.outputs.text }}"
}
upload-release-artifacts:
needs:
[
set-metadata,
release-create,
build-macos,
build-windows,
build-linux,
build-android,
build-ios,
]
if: |
!cancelled() &&
needs.release-create.result == 'success' &&
(needs.build-macos.result == 'success' || needs.build-macos.result == 'skipped') &&
(needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped') &&
(needs.build-linux.result == 'success' || needs.build-linux.result == 'skipped') &&
(needs.build-android.result == 'success' || needs.build-android.result == 'skipped') &&
(needs.build-ios.result == 'success' || needs.build-ios.result == 'skipped') &&
(needs.build-macos.result == 'success' || needs.build-windows.result == 'success' ||
needs.build-linux.result == 'success' || needs.build-android.result == 'success' ||
needs.build-ios.result == 'success')
runs-on: ubuntu-latest
env:
BUILD_TYPE: ${{ needs.set-metadata.outputs.build_type }}
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
INSTALLER_BASE_NAME: ${{ needs.set-metadata.outputs.installer_base_name }}
PLATFORM: ${{ needs.set-metadata.outputs.platform }}
LINUX_ARCH: ${{ needs.set-metadata.outputs.linux_arch }}
BUCKET: ${{ vars.S3_RELEASES_BUCKET }}
GITHUB_REF_NAME: ${{ github.ref_name }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Download build artifacts
uses: actions/download-artifact@v4
- name: Update release notes
env:
GH_TOKEN: ${{ github.token }}
GITHUB_SHA: ${{ github.sha }}
RELEASE_TAG: ${{ env.RELEASE_TAG }}
run: |
# Generate release notes
./scripts/ci/format.sh release-notes > release_notes.md
# Update the draft release with proper notes
gh release edit "$RELEASE_TAG" --notes-file release_notes.md
- name: Upload artifacts to GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
# Construct full filename with build type (Makefile appends it)
FULL_NAME="${INSTALLER_BASE_NAME}"
[[ -n "$BUILD_TYPE" && "$BUILD_TYPE" != "production" ]] && FULL_NAME="${FULL_NAME}-${BUILD_TYPE}"
upload_if_exists() {
local file="$1"
if [[ -f "$file" ]]; then
echo "Uploading $file to GitHub release..."
gh release upload "$RELEASE_TAG" "$file" --clobber
fi
}
upload_if_exists "lantern-installer-dmg/${FULL_NAME}.dmg"
upload_if_exists "lantern-installer-exe/${FULL_NAME}.exe"
upload_if_exists "lantern-installer-apk/${FULL_NAME}.apk"
upload_if_exists "lantern-installer-deb-amd64/${FULL_NAME}.deb"
upload_if_exists "lantern-installer-rpm-amd64/${FULL_NAME}.rpm"
upload_if_exists "lantern-installer-deb-arm64/${FULL_NAME}-arm64.deb"
upload_if_exists "lantern-installer-rpm-arm64/${FULL_NAME}-arm64.rpm"
upload_if_exists "lantern-installer-deb/${FULL_NAME}.deb"
upload_if_exists "lantern-installer-rpm/${FULL_NAME}.rpm"
upload_if_exists "lantern-installer-ipa/${FULL_NAME}.ipa"
# Post-publish steps (only for non-nightly production/beta builds)
upload-google-play:
needs: [set-metadata, build-android]
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.build-android.result == 'success' &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'android')) &&
(needs.set-metadata.outputs.build_type == 'beta' || needs.set-metadata.outputs.build_type == 'production')
runs-on: ubuntu-latest
steps:
- name: Download AAB artifact
uses: actions/download-artifact@v4
with:
name: lantern-installer-aab
path: aab
- name: Download mapping.txt
uses: actions/download-artifact@v4
with:
name: play-mapping
path: play
- name: Download native debug symbols
uses: actions/download-artifact@v4
with:
name: play-debug-symbols
path: play
- name: Pick Play track
id: track
run: |
bt="${{ needs.set-metadata.outputs.build_type }}"
if [ "$bt" = "beta" ]; then
echo "track=beta" >> "$GITHUB_OUTPUT"
else
echo "track=production" >> "$GITHUB_OUTPUT"
fi
- name: Upload to Google Play
uses: r0adkll/upload-google-play@v1.1.3
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
packageName: org.getlantern.lantern
releaseFiles: aab/*.aab
track: ${{ steps.track.outputs.track }}
status: completed
mappingFile: play/mapping.txt
debugSymbols: play/debug-symbols.zip
upload-testflight:
needs: [set-metadata, build-ios]
if: |
!cancelled() &&
needs.set-metadata.result == 'success' &&
needs.build-ios.result == 'success' &&
(needs.set-metadata.outputs.platform == 'all' || contains(needs.set-metadata.outputs.platform, 'ios')) &&
(needs.set-metadata.outputs.build_type == 'beta' || needs.set-metadata.outputs.build_type == 'production')
runs-on: macos-14
steps:
- name: Download iOS Artifact
uses: actions/download-artifact@v4
with:
name: lantern-installer-ipa
path: .
- name: Construct IPA filename
id: filename
shell: bash
run: |
FULL_NAME="${{ needs.set-metadata.outputs.installer_base_name }}"
BUILD_TYPE="${{ needs.set-metadata.outputs.build_type }}"
[[ -n "$BUILD_TYPE" && "$BUILD_TYPE" != "production" ]] && FULL_NAME="${FULL_NAME}-${BUILD_TYPE}"
echo "ipa=${FULL_NAME}.ipa" >> "$GITHUB_OUTPUT"
- name: Upload to TestFlight
uses: apple-actions/upload-testflight-build@v3.0.1
with:
app-path: ${{ steps.filename.outputs.ipa }}
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
api-key-id: ${{ secrets.APPSTORE_API_KEY_ID }}
api-private-key: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
update-appcast:
needs: [set-metadata, release-finalize]
if: |
!cancelled() &&
needs.release-finalize.result == 'success' &&
(needs.set-metadata.outputs.platform == 'all' ||
contains(needs.set-metadata.outputs.platform, 'macos') ||
contains(needs.set-metadata.outputs.platform, 'windows') ||
contains(needs.set-metadata.outputs.platform, 'linux')) &&
needs.set-metadata.outputs.build_type != 'nightly'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Install Flutter
uses: subosito/flutter-action@v2.22.0
with:
channel: stable
flutter-version-file: .github/flutter-version.yaml
- name: Install Python dependencies
run: python3 -m pip install -r scripts/requirements.txt
- name: Update appcast.xml
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB_TOKEN: ${{ secrets.CI_PRIVATE_REPOS_GH_TOKEN }}
BUILD_TYPE: ${{ needs.set-metadata.outputs.build_type }}
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
BUCKET: ${{ vars.S3_RELEASES_BUCKET }}
run: |
# Strip 'v' prefix for S3 paths
VERSION="${RELEASE_TAG#v}"
python3 scripts/generate_appcast.py
# appcast, like installers, always upload a versioned copy alongside "latest"
aws s3 cp appcast.xml "s3://${BUCKET}/releases/${BUILD_TYPE}/${VERSION}/appcast.xml" --acl public-read
aws s3 cp appcast.xml "s3://${BUCKET}/releases/${BUILD_TYPE}/latest/appcast.xml" --acl public-read
if [[ "$BUILD_TYPE" == "production" ]]; then
aws s3 cp appcast.xml "s3://${BUCKET}/releases/appcast.xml" --acl public-read
fi
# Upload appcast.xml to GitHub release, but
# not git because we may be in detached HEAD
gh release upload "$RELEASE_TAG" appcast.xml --clobber
release-finalize:
needs:
[
set-metadata,
upload-s3,
upload-release-artifacts,
upload-google-play,
upload-testflight,
]
if: always()
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
BUILD_TYPE: ${{ needs.set-metadata.outputs.build_type }}
CLEANUP_ON_FAILURE: ${{ github.event.inputs.cleanup_on_failure != 'false' }}
IS_TEST_RUN: ${{ needs.set-metadata.outputs.is_test_run }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Publish release on success
if: |
env.IS_TEST_RUN != 'true' &&
env.BUILD_TYPE != 'nightly' &&
needs.upload-s3.result == 'success' &&
needs.upload-release-artifacts.result == 'success' &&
(needs.upload-google-play.result == 'success' || needs.upload-google-play.result == 'skipped') &&
(needs.upload-testflight.result == 'success' || needs.upload-testflight.result == 'skipped')
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "All steps succeeded - publishing draft release"
gh release edit "$RELEASE_TAG" --draft=false
- name: Delete draft release
if: |
env.IS_TEST_RUN == 'true' ||
env.BUILD_TYPE == 'nightly' ||
(env.CLEANUP_ON_FAILURE == 'true' &&
!(needs.upload-s3.result == 'success' &&
needs.upload-release-artifacts.result == 'success' &&
(needs.upload-google-play.result == 'success' || needs.upload-google-play.result == 'skipped') &&
(needs.upload-testflight.result == 'success' || needs.upload-testflight.result == 'skipped')))
env:
GH_TOKEN: ${{ github.token }}
run: |
if [[ "$IS_TEST_RUN" == "true" ]]; then
echo "Test run from non-main branch - deleting draft release"
elif [[ "$BUILD_TYPE" == "nightly" ]]; then
echo "Nightly build - deleting draft release"
else
echo "Build failed or cancelled - cleaning up draft release"
fi
attempt=0
max_retries=5
while [ "$attempt" -lt "$max_retries" ]; do
attempt=$((attempt + 1))
echo "Deleting release $RELEASE_TAG (attempt $attempt/$max_retries)..."
if gh release delete "$RELEASE_TAG" --yes --cleanup-tag 2>&1; then
echo "Release $RELEASE_TAG deleted"
break
fi
if [ "$attempt" -eq "$max_retries" ]; then
echo "Failed to delete release after $max_retries attempts"
exit 1
fi
sleep 3
done
- name: Report failure (cleanup disabled)
if: |
env.IS_TEST_RUN != 'true' &&
env.BUILD_TYPE != 'nightly' &&
env.CLEANUP_ON_FAILURE != 'true' &&
!(needs.upload-s3.result == 'success' &&
needs.upload-release-artifacts.result == 'success' &&
(needs.upload-google-play.result == 'success' || needs.upload-google-play.result == 'skipped') &&
(needs.upload-testflight.result == 'success' || needs.upload-testflight.result == 'skipped'))
run: |
echo "Build failed or cancelled - draft release preserved for inspection"
echo "Draft: https://github.com/getlantern/lantern/releases/tag/$RELEASE_TAG"
exit 1