Skip to content

Build and Publish #1290

Build and Publish

Build and Publish #1290

Workflow file for this run

name: Build and Publish
# This workflow is triggered on pushes to the main branch, pull requests and manual triggers
# 1. version - An initial step to be used by other steps - bumps the version code and string based on the run number and package.json
# 2. android - Builds the Android app and uploads it to Google Play (if requested)
# 3. docker - Builds the Docker image and pushes it to GitHub Container Registry
# 4. ios - Builds the iOS app and uploads it to App Store (if requested)
# 5. github-release - Tags the commit and creates a Github release with the apps' binaries (if requested)
on:
workflow_dispatch:
inputs:
publishandroid:
description: 'Publish to Google play'
required: false
default: 'false'
type: boolean
publishios:
description: 'Publish to App Store'
required: false
default: 'false'
type: boolean
production:
description: 'Publish to production'
required: false
default: 'false'
type: boolean
jobs:
version:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6.4.0
with:
node-version-file: IsraelHiking.Web/.nvmrc
- name: Get version
id: get-version
run: |
version=$(node -p "require('./IsraelHiking.Web/package.json').version")
echo "major=${version%%.*}" >> "$GITHUB_OUTPUT"
echo "minor=$(echo "$version" | cut -d. -f2)" >> "$GITHUB_OUTPUT"
- name: Set version code and string
id: version-code
env:
MAJOR: ${{ steps.get-version.outputs.major }}
MINOR: ${{ steps.get-version.outputs.minor }}
PATCH: ${{ github.run_number }}
run: |
version_string=$MAJOR.$MINOR.$(($PATCH % 1000))
echo "version_code=$(($MAJOR * 100000 + $MINOR * 1000 + $PATCH % 1000))" >> $GITHUB_OUTPUT
echo "version_string=$version_string" >> $GITHUB_OUTPUT
echo "Version: $version_string" >> $GITHUB_STEP_SUMMARY
- name: Get all milestones
id: get_milestones
uses: octokit/request-action@v3.0.0
with:
route: GET /repos/${{ github.repository }}/milestones?state=open
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract milestone ID
id: extract
run: |
echo '${{ steps.get_milestones.outputs.data }}' | jq '.[] | select(.title == "Next Release") | .number' > id.txt
milestone_id=$(cat id.txt)
echo "milestone_id=$milestone_id" >> $GITHUB_OUTPUT
shell: bash
outputs:
version_code: ${{ steps.version-code.outputs.version_code }}
version_string: ${{ steps.version-code.outputs.version_string }}
milestone_id: ${{ steps.extract.outputs.milestone_id }}
android:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6.4.0
with:
node-version-file: IsraelHiking.Web/.nvmrc
- name: Setup Java
uses: actions/setup-java@v5.5.0
with:
distribution: 'temurin'
java-version: '21'
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4.1'
working-directory: IsraelHiking.Web/android
bundler-cache: true
- name: Build UI and set version
run: |
cd IsraelHiking.Web
npm ci
npm run set-version ${{ needs.version.outputs.version_string }} ${{ needs.version.outputs.version_code }}
npm run build:mobile -- --no-progress
npx cap sync android
- name: Build Android Release
if: ${{ github.secret_source == 'Actions' }}
run: |
cd IsraelHiking.Web/android
bundle exec fastlane build_aab
bundle exec fastlane build_apk
env:
STORE_PASSWORD: ${{ secrets.MAPEAK_STORE_PASSWORD }}
PASSWORD: ${{ secrets.MAPEAK_PASSWORD }}
KEYSTORE_PATH: ${{ github.workspace }}/IsraelHiking.Web/android/app/Mapeak.jks
- name: Upload aab artifacts
if: ${{ github.secret_source == 'Actions' }}
uses: actions/upload-artifact@v7.0.1
with:
name: Mapeak_signed_${{ needs.version.outputs.version_string }}.aab
path: IsraelHiking.Web/android/app/build/outputs/bundle/release/app-release.aab
- name: Upload apk artifacts
if: ${{ github.secret_source == 'Actions' }}
uses: actions/upload-artifact@v7.0.1
with:
name: Mapeak_signed_${{ needs.version.outputs.version_string }}.apk
path: IsraelHiking.Web/android/app/build/outputs/apk/release/app-release.apk
- name: Publish to Google Play
if: ${{ github.event.inputs.publishandroid == 'true' }}
run: |
cd IsraelHiking.Web/android
bundle exec fastlane upload
env:
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
- name: Promote to production
if: ${{ github.event.inputs.publishandroid == 'true' && github.event.inputs.production == 'true' }}
run: |
cd IsraelHiking.Web/android
bundle exec fastlane promote
env:
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
docker:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Login to GitHub Container Registry
if: ${{ github.secret_source == 'Actions' }}
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image
run: |
docker build . -t ghcr.io/israelhikingmap/website-mapeak:$VERSION --build-arg VERSION=$VERSION
env:
VERSION: ${{ needs.version.outputs.version_string }}
- name: Push Docker image
if: ${{ github.secret_source == 'Actions' }}
run: |
docker push ghcr.io/israelhikingmap/website-mapeak:$VERSION
env:
VERSION: ${{ needs.version.outputs.version_string }}
ios:
runs-on: macos-26
needs: version
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6.4.0
with:
node-version-file: IsraelHiking.Web/.nvmrc
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4.1'
working-directory: IsraelHiking.Web/ios/App
bundler-cache: true
- name: Set up Git to use PAT for private match repo
run: |
git config --global url."https://x-access-token:${{ secrets.FASTLANE_MATCH_PAT }}@github.com/IsraelHikingMap/fastlane-match".insteadOf "https://github.com/IsraelHikingMap/fastlane-match"
- name: Build UI
run: |
cd IsraelHiking.Web
npm ci
npm run set-version ${{ needs.version.outputs.version_string }} ${{ needs.version.outputs.version_code }}
npm run build:mobile -- --no-progress
npx cap sync ios
- name: Build iOS with signing
if: ${{ github.secret_source == 'Actions' }}
run: |
cd IsraelHiking.Web/ios/App
bundle exec fastlane build_ios
env:
MATCH_PASSWORD: ${{ secrets.PASSWORD }}
- name: Upload ipa artifacts
if: ${{ github.secret_source == 'Actions' }}
uses: actions/upload-artifact@v7.0.1
with:
name: Mapeak_signed_${{ needs.version.outputs.version_string }}.ipa
path: IsraelHiking.Web/ios/App/App.ipa
- name: Upload to testers
if: ${{ github.event.inputs.publishios == 'true' && github.event.inputs.production == 'false' }}
run: |
cd IsraelHiking.Web/ios/App
bundle exec fastlane upload_to_testers
env:
APPSTORE_CONNECT_API_KEY: ${{ secrets.APPSTORE_CONNECT_API_KEY }}
- name: Upload and send for review
if: ${{ github.event.inputs.publishios == 'true' && github.event.inputs.production == 'true' }}
run: |
cd IsraelHiking.Web/ios/App
bundle exec fastlane upload_to_production
env:
APPSTORE_CONNECT_API_KEY: ${{ secrets.APPSTORE_CONNECT_API_KEY }}
github-release:
if: ${{ github.event.inputs.production == 'true' }}
runs-on: ubuntu-latest
needs: [version, ios, android]
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Tag commit and push
run: |
git tag "v${{ needs.version.outputs.version_string }}"
git push origin "v${{ needs.version.outputs.version_string }}"
- name: Download artifacts
uses: actions/download-artifact@v8
with:
path: ${{ github.workspace }}/artifacts
merge-multiple: true
- name: Rename artifacts
run: |
mv ${{ github.workspace }}/artifacts/*.ipa ${{ github.workspace }}/Mapeak_signed_${{ needs.version.outputs.version_string }}.ipa
mv ${{ github.workspace }}/artifacts/*.aab ${{ github.workspace }}/Mapeak_signed_${{ needs.version.outputs.version_string }}.aab
mv ${{ github.workspace }}/artifacts/*.apk ${{ github.workspace }}/Mapeak_signed_${{ needs.version.outputs.version_string }}.apk
- name: Rename and close milestone
uses: octokit/request-action@v3.0.0
with:
route: PATCH /repos/${{ github.repository }}/milestones/${{ needs.version.outputs.milestone_id }}
title: Version ${{ needs.version.outputs.version_string }}
state: closed
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create new "Next Release" milestone
uses: octokit/request-action@v3.0.0
with:
route: POST /repos/${{ github.repository }}/milestones
title: Next Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.version.outputs.version_string }}
name: v${{ needs.version.outputs.version_string }}
body: |
See [Milestone ${{ needs.version.outputs.version_string }}](https://github.com/${{ github.repository }}/milestone/${{ needs.version.outputs.milestone_id }}?closed=1)
token: ${{ secrets.GITHUB_TOKEN }}
files: |
Mapeak_signed_${{ needs.version.outputs.version_string }}.ipa
Mapeak_signed_${{ needs.version.outputs.version_string }}.aab
Mapeak_signed_${{ needs.version.outputs.version_string }}.apk