Files
5chan/.github/workflows/release.yml
T

344 lines
12 KiB
YAML

# docs https://github.com/marketplace/actions/create-release
# docs https://github.com/ncipollo/release-action
# docs https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job#choosing-github-hosted-runners
#
# Architecture: build jobs upload workflow artifacts only. A single
# finalize-release job creates the GitHub release with all assets + body.
# If ANY build job fails, finalize-release is skipped and no release appears.
name: release
on:
push:
tags:
- 'v*'
jobs:
preflight:
runs-on: ubuntu-22.04
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Run Vitest
run: yarn test --run
- name: Lint
run: yarn lint
- name: Type check
run: yarn type-check
- name: Build React app
run: CI='' NODE_ENV=production yarn build
- name: Run React Doctor
run: yarn doctor
- name: Install Chromium for smoke tests
run: npx playwright install --with-deps chromium
- name: Smoke test built web app
run: node scripts/smoke-web-app.js --start-preview
linux:
strategy:
fail-fast: false
matrix:
arch: [x64, arm64]
runs-on: ubuntu-22.04
needs: preflight
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Download IPFS and set permissions
run: BUILD_ARCH=${{ matrix.arch }} node electron/download-ipfs && sudo chmod +x bin/linux/ipfs
- name: Build React app
run: CI='' NODE_ENV=production yarn build
- name: Build Electron app for Linux (arm64)
if: matrix.arch == 'arm64'
run: yarn electron:build:linux:arm64
- name: Build Electron app for Linux (x64)
if: matrix.arch == 'x64'
run: yarn electron:build:linux:x64
- name: Stage release artifacts
run: |
mkdir -p release-assets
VERSION=$(node -e "console.log(require('./package.json').version)")
APPIMAGE_PATH=$(find out/make/AppImage -name '*.AppImage' | head -n 1)
[ -n "$APPIMAGE_PATH" ] || exit 1
cp "$APPIMAGE_PATH" "release-assets/5chan-${VERSION}-${{ matrix.arch }}.AppImage"
- name: Create static HTML release archive
if: matrix.arch == 'x64'
run: |
VERSION=$(node -e "console.log(require('./package.json').version)")
HTML_ARCHIVE_DIR="5chan-$VERSION-html"
rm -rf "$HTML_ARCHIVE_DIR"
cp -R build "$HTML_ARCHIVE_DIR"
zip -r "release-assets/${HTML_ARCHIVE_DIR}.zip" "$HTML_ARCHIVE_DIR"
rm -rf "$HTML_ARCHIVE_DIR"
- name: List release assets
run: ls -la release-assets
- uses: actions/upload-artifact@v4
with:
name: release-linux-${{ matrix.arch }}
path: release-assets/
mac:
strategy:
fail-fast: false
matrix:
include:
- runner: macos-15-intel # Intel x64
arch: x64
- runner: macos-latest # Apple Silicon arm64
arch: arm64
runs-on: ${{ matrix.runner }}
needs: preflight
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install setuptools
- name: Install dependencies
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Download IPFS and set permissions
run: node electron/download-ipfs && sudo chmod +x bin/mac/ipfs
- name: Build React app
run: CI='' NODE_ENV=production yarn build
- name: Build Electron app for Mac
env:
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
run: |
if [ "${{ matrix.arch }}" = "arm64" ]; then
yarn electron:build:mac:arm64
else
yarn electron:build:mac:x64
fi
- name: Stage release artifacts
run: |
mkdir -p release-assets
VERSION=$(node -e "console.log(require('./package.json').version)")
DMG_PATH=$(find out/make -maxdepth 1 -name '*.dmg' | head -n 1)
ZIP_PATH=$(find out/make/zip -name '*.zip' | head -n 1)
[ -n "$DMG_PATH" ] || exit 1
[ -n "$ZIP_PATH" ] || exit 1
cp "$DMG_PATH" "release-assets/5chan-${VERSION}-${{ matrix.arch }}.dmg"
cp "$ZIP_PATH" "release-assets/5chan-${VERSION}-${{ matrix.arch }}.zip"
- name: List release assets
run: ls -la release-assets
- uses: actions/upload-artifact@v4
with:
name: release-mac-${{ matrix.arch }}
path: release-assets/
windows:
runs-on: windows-2022
needs: preflight
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- name: Resolve Yarn cache path
id: yarn-cache
shell: bash
run: echo "dir=$(corepack yarn config get cacheFolder)" >> "$GITHUB_OUTPUT"
- name: Cache Yarn package tarballs
uses: actions/cache@v4
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock', 'package.json', '.yarnrc.yml') }}
restore-keys: ${{ runner.os }}-yarn-v1-
- name: Cache electron binaries
uses: actions/cache@v4
with:
path: ~/AppData/Local/electron/Cache
key: ${{ runner.os }}-electron-v2-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-electron-v2-
- name: Install dependencies
shell: bash
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Build React app
run: npx cross-env NODE_ENV=production yarn build
- name: Build Electron app for Windows (x64)
run: yarn electron:build:windows
- name: Stage release artifacts
shell: bash
run: |
mkdir -p release-assets
VERSION=$(node -e "console.log(require('./package.json').version)")
SETUP_EXE_PATH=$(find out/make -iname '*setup*.exe' | head -n 1)
[ -n "$SETUP_EXE_PATH" ] || exit 1
cp "$SETUP_EXE_PATH" "release-assets/5chan-${VERSION}-x64.Setup.exe"
- name: List release assets
shell: bash
run: ls -la release-assets
- uses: actions/upload-artifact@v4
with:
name: release-windows
path: release-assets/
android:
runs-on: ubuntu-22.04
needs: preflight
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- run: sudo apt-get install -y apksigner zipalign
- name: Install dependencies
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Build React app
run: CI='' NODE_ENV=production yarn build
- name: Set Android versionCode and versionName
run: |
VERSION=$(node -e "console.log(require('./package.json').version)")
VERSION_CODE=$(node -e "const [major = 0, minor = 0, patch = 0] = require('./package.json').version.replace(/^v/, '').split('-')[0].split('.').map(Number); console.log((major * 10000) + (minor * 100) + patch)")
echo "APP_VERSION_NAME=${VERSION}" >> "$GITHUB_ENV"
echo "APP_VERSION_CODE=${VERSION_CODE}" >> "$GITHUB_ENV"
echo "Android versionName=${VERSION} versionCode=${VERSION_CODE}"
- name: Sync Capacitor
run: npx cap sync android
- name: Build APK
run: |
for i in 1 2 3; do
echo "gradlew assembleGithubRelease attempt $i"
(cd android && ./gradlew assembleGithubRelease -PAPP_VERSION_NAME="${APP_VERSION_NAME}" -PAPP_VERSION_CODE="${APP_VERSION_CODE}" --stacktrace) && break
sleep 10
[ "$i" = "3" ] && exit 1
done
- name: Optimize APK
run: cd android/app/build/outputs/apk/github/release && zipalign 4 app-github-release-unsigned.apk app-github-release-unsigned-zip.apk
- name: Sign APK
run: cd android/app/build/outputs/apk/github/release && apksigner sign --ks ../../../../../../plebbit.keystore --ks-pass pass:${{ secrets.PLEBBIT_REACT_KEYSTORE_PASSWORD }} --ks-key-alias release --out app-github-release-signed.apk app-github-release-unsigned-zip.apk
- name: Stage release artifacts
run: |
mkdir -p release-assets
VERSION=$(node -e "console.log(require('./package.json').version)")
mv android/app/build/outputs/apk/github/release/app-github-release-signed.apk "release-assets/5chan-${VERSION}.apk"
- name: List release assets
run: ls -la release-assets
- uses: actions/upload-artifact@v4
with:
name: release-android
path: release-assets/
finalize-release:
runs-on: ubuntu-22.04
needs: [linux, mac, windows, android]
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: |
for i in 1 2 3; do
echo "yarn install attempt $i"
yarn install --immutable && break
sleep 5
[ "$i" = "3" ] && exit 1
done
- name: Download all release artifacts
uses: actions/download-artifact@v4
with:
pattern: release-*
path: release-assets
merge-multiple: true
- name: List all release assets
run: ls -la release-assets
- name: Populate dist for release-body script
run: |
mkdir -p dist
cp release-assets/* dist/
- name: Generate release body
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REF_NAME: ${{ github.ref_name }}
run: node scripts/release-body > release-body.txt
- name: Create GitHub release
uses: ncipollo/release-action@v1
with:
artifacts: 'release-assets/*'
bodyFile: "release-body.txt"
allowUpdates: true
token: ${{ secrets.GITHUB_TOKEN }}