185 lines
7.4 KiB
YAML
185 lines
7.4 KiB
YAML
---
|
|
name: Release
|
|
|
|
on:
|
|
# Publishing a release guarantees the release exists before production submissions begin.
|
|
# The release job below only accepts numeric semver tags matching package.json.
|
|
release:
|
|
types: [published]
|
|
|
|
# Key each parent run by tag so a newly published release cannot evict a different pending run.
|
|
# The reusable platform workflows retain their own concurrency groups to serialize app builds.
|
|
concurrency:
|
|
group: release-${{ github.event.release.tag_name }}
|
|
cancel-in-progress: false
|
|
|
|
# Permissions are granted per job. The mobile build jobs only receive the secrets declared by
|
|
# their reusable workflows rather than the repository's entire secret store.
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
release:
|
|
name: Validate release tag
|
|
if: github.repository == 'bluesky-social/social-app'
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.version.outputs.version }}
|
|
steps:
|
|
- name: ⬇️ Checkout release commit
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: 🔎 Validate release tag and version
|
|
id: version
|
|
env:
|
|
RELEASE_TAG: ${{ github.ref_name }}
|
|
run: |
|
|
version=$(jq -r '.version' package.json)
|
|
if ! [[ "$RELEASE_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "::error::Release tag must be a semver version such as 1.130.0; found '$RELEASE_TAG'."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$RELEASE_TAG" != "$version" ]; then
|
|
echo "::error file=package.json::Release tag is $RELEASE_TAG, but package.json is version $version."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Releasing $version from $GITHUB_SHA"
|
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
|
|
ios:
|
|
name: Production iOS Build
|
|
needs: [release]
|
|
uses: ./.github/workflows/build-submit-ios.yml
|
|
with:
|
|
profile: production
|
|
testFlightGroup: "QA Team"
|
|
secrets:
|
|
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
|
|
ENV_TOKEN: ${{ secrets.ENV_TOKEN }}
|
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
|
BITDRIFT_API_KEY: ${{ secrets.BITDRIFT_API_KEY }}
|
|
EXPO_PUBLIC_GCP_PROJECT_ID: ${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}
|
|
GOOGLE_SERVICES_TOKEN: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
|
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
|
|
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
|
ASC_KEY_P8_BASE64: ${{ secrets.ASC_KEY_P8_BASE64 }}
|
|
SLACK_CLIENT_ALERT_WEBHOOK: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
|
|
|
android:
|
|
name: Production Android Build
|
|
needs: [release]
|
|
# The reusable workflow's APK attachment job needs this permission. The build and submit
|
|
# jobs remain read-only through their own job/workflow permission declarations.
|
|
permissions:
|
|
contents: write
|
|
uses: ./.github/workflows/build-submit-android.yml
|
|
with:
|
|
profile: production
|
|
secrets:
|
|
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
|
|
ENV_TOKEN: ${{ secrets.ENV_TOKEN }}
|
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
|
BITDRIFT_API_KEY: ${{ secrets.BITDRIFT_API_KEY }}
|
|
EXPO_PUBLIC_GCP_PROJECT_ID: ${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}
|
|
GOOGLE_SERVICES_TOKEN: ${{ secrets.GOOGLE_SERVICES_TOKEN }}
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
|
SLACK_CLIENT_ALERT_WEBHOOK: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
|
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
|
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
|
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
|
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
|
|
|
bump-version:
|
|
name: Open next version PR
|
|
needs: [release, ios, android]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
steps:
|
|
# The builds can take long enough for main to advance. Base the bump on the latest main,
|
|
# but verify its version is still the one that this workflow just released.
|
|
- name: ⬇️ Checkout latest main
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: main
|
|
persist-credentials: false
|
|
|
|
- name: 🧮 Compute next version
|
|
id: version
|
|
env:
|
|
RELEASED: ${{ needs.release.outputs.version }}
|
|
run: |
|
|
current=$(jq -r '.version' package.json)
|
|
if [ "$current" != "$RELEASED" ]; then
|
|
echo "::error file=package.json::main is now version $current, but this workflow released $RELEASED. Refusing to overwrite a newer version."
|
|
exit 1
|
|
fi
|
|
|
|
next=$(echo "$RELEASED" | jq -R -r 'split(".") | "\(.[0]).\(.[1] | tonumber + 1).0"')
|
|
echo "Bumping $RELEASED to $next"
|
|
echo "next=$next" >> "$GITHUB_OUTPUT"
|
|
echo "branch=bot/version-bump-$next" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: 🔁 Check for an existing version-bump PR
|
|
id: dedup
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
BRANCH: ${{ steps.version.outputs.branch }}
|
|
run: |
|
|
existing=$(gh pr list --state open --head "$BRANCH" --json url --jq '.[0].url // ""')
|
|
if [ -n "$existing" ]; then
|
|
echo "Version-bump PR already exists: $existing"
|
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: ✏️ Bump version
|
|
if: steps.dedup.outputs.skip == 'false'
|
|
env:
|
|
NEXT: ${{ steps.version.outputs.next }}
|
|
run: |
|
|
jq --indent 2 --arg version "$NEXT" '.version = $version' package.json > package.json.tmp
|
|
mv package.json.tmp package.json
|
|
|
|
changed=$(git diff --numstat package.json | awk '{print $1"+"$2}')
|
|
if [ "$changed" != "1+1" ]; then
|
|
echo "::error file=package.json::Expected the version bump to change exactly one line."
|
|
git diff -- package.json
|
|
exit 1
|
|
fi
|
|
|
|
- name: 📤 Create branch and pull request
|
|
if: steps.dedup.outputs.skip == 'false'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
BRANCH: ${{ steps.version.outputs.branch }}
|
|
NEXT: ${{ steps.version.outputs.next }}
|
|
RELEASED: ${{ needs.release.outputs.version }}
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
|
|
|
|
# A previous attempt may have pushed this deterministic bot branch and then failed
|
|
# before creating its PR. Fetch it so force-with-lease can replace only that known tip.
|
|
git fetch origin "$BRANCH:refs/remotes/origin/$BRANCH" || true
|
|
git checkout -B "$BRANCH"
|
|
git add package.json
|
|
git commit -m "bump version to $NEXT"
|
|
git push --force-with-lease --set-upstream origin "$BRANCH"
|
|
|
|
# This requires "Allow GitHub Actions to create and approve pull requests" in the
|
|
# repository's Actions settings; no long-lived personal access token is needed.
|
|
gh pr create \
|
|
--base main \
|
|
--head "$BRANCH" \
|
|
--title "Bump version to $NEXT" \
|
|
--body "Released $RELEASED. Bumps the app version to $NEXT for the next release cycle."
|