Skip to content

Commit

Permalink
WIP CI workflows and Fastlane
Browse files Browse the repository at this point in the history
Issue: SIMPLYE-381
  • Loading branch information
kankaristo committed Jun 13, 2024
1 parent 758bb50 commit d44d450
Show file tree
Hide file tree
Showing 96 changed files with 8,778 additions and 596 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
88 changes: 88 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# GitHub Actions workflows

This directory contains E-kirjasto iOS CI workflows.


## Secrets

Secrets are stored in GitHub Actions and are available to the workflows as
environment variables.
The secrets are stored in the respective repository,
so secrets for the Android CI workflows are stored in ekirjasto-android-core,
while secrets for the iOS CI workflows are stored in ekirjasto-ios-core, etc.

GitHub Actions doesn't directly support storing files, so files are stored as
base64 encoded strings and decoded back into files (by `scripts/reveal-secrets.sh`).

[ekirjasto-ci-helper](https://github.com/NatLibFi/ekirjasto-ci-helper) is used
to manage the secrets.
It cannot read the secrets, but it can be used to set or delete secrets.
It requires a GitHub personal access token with rights to the repository.


### iOS secrets

The secrets in use for the iOS CI workflows are:

| Secret name | Environment variable | Format | Description |
|-----------------------------------------|----------------------------------------------------------|--------|--------------------------------------------------|
| FASTLANE_APP_STORE_CONNECT_API_KEY_JSON | EKIRJASTO_FASTLANE_APP_STORE_CONNECT_API_KEY_JSON_BASE64 | base64 | App Store Connect API key JSON (base64 encoded) |
| LIBLCP_DEPENDECY_SECRET | EKIRJASTO_LIBLCP_DEPENDENCY_SECRET | text | The secret part of the liblcp dependency path |
| MATCH_PASSWORD | MATCH_PASSWORD | text | Password for Fastlane match (ekirjasto-ios-keys) |
| SSH_PRIVATE_KEY | N/A | text | SSH private key (E-kirjasto CI machine account) |
| TRANSIFEX_SECRET | EKIRJASTO_IOS_TRANSIFEX_SECRET | text | The iOS Transifex secret |
| TRANSIFEX_TOKEN | EKIRJASTO_IOS_TRANSIFEX_TOKEN | text | The iOS Transifex token |


### Log masking secrets

In addition to the above secrets, there are some additional values where the
name starts with `MASK_`. These secrets are not used at all in the build, and
their purpose just to mask the values from GitHub Actions logs (there are other
ways to achieve log masking, but this is the easiest method).

For example, the liblcp dependency path in `Cartfile` is a secret and should be
masked in logs, but the entire file is stored as one secret, so the individual
dependecy path would not be automatically masked without the `MASK_*` secrets.


## iOS CI workflows

### ios-pr.yml

This workflow is run for every commit pushed to a PR.

This workflow builds a debug build with the production configuration,
and release builds for the dev, beta, and productions configurations,
and runs tests.


### ios-main.yml

This workflow is run for every commit pushed to the main branch.
Direct commits to main are disabled, so essentially this is run for merged PRs.

This workflow does the same builds and runs the same tests as the PR workflow,
but in addition to those, the dev, beta and production release builds are uploaded to Testflight.
Before the uploads, some minimal release checks are run,
so that uploads wouldn't fail because of things like a version suffix.


### ios-release.yml

This workflow is run for commits on release/* branches (e.g. release/1.2.3).

This workflow is mostly the same as the main CI workflow,
meaning that all builds and tests are run,
and the same uploads are made, but some additional release checks are made.

Before the uploads some additional checks are run:
- there must not be any suffix in the version name (also checked in the main workflow)
- while Xcode allows using a suffix for iOS apps, App Store Connect will not allow using any suffix
- the version number must be increased from the one currently in main
- all Transifex strings must be committed into the repository
- i.e. `scripts/transifex.sh` must not find new strings to download

The main purpose of this workflow is to automate releasing a new version,
but not everything is automated (by design). See [RELEASING.md](/RELEASING.md)
for what to do after upload and more info about E-kirjasto's releasing process.
81 changes: 81 additions & 0 deletions .github/workflows/ios-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: ios-main

#
# This workflow is run on all commits pushed to main (i.e. merged PRs).
#

on:
push:
branches: [ main ]

env:
COMMIT_SHA: ${{ github.sha }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
TARGET_BRANCH_NAME: ${{ github.base_ref || github.ref_name }}
# Join all secrets, so that they're "used", and will be masked in logs
MASKED_SECRETS: ${{ join(secrets, '\n') }}

jobs:
build:
runs-on: macOS-13
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Show build info
env:
TEST_SECRET: ${{ secrets.MASK_TEST }}
run: scripts/show-ci-info.sh

- name: SSH setup (for cloning ekirjasto-ios-keys through Fastlane match)
uses: MrSquaare/[email protected]
with:
private-key-name: ekirjasto-ci-ed25519
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
host: github.com
- name: Force Xcode 15
run: sudo xcode-select -switch /Applications/Xcode_15.0.1.app

- name: Bootstrap (and reveal secrets)
env:
EKIRJASTO_FASTLANE_APP_STORE_CONNECT_API_KEY_JSON_BASE64: ${{ secrets.FASTLANE_APP_STORE_CONNECT_API_KEY_JSON }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
EKIRJASTO_LIBLCP_DEPENDENCY_SECRET: ${{ secrets.LIBLCP_DEPENDENCY_SECRET }}
# Carthage gets rate limited in GitHub Actions if unauthenticated
# (they're all public repositories, so auth isn't otherwise necessary)
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: scripts/bootstrap.sh --overwrite-secrets

- name: App version and build number consistency check
run: scripts/version.sh --check

- name: Upload and download Transifex localizations
env:
EKIRJASTO_IOS_TRANSIFEX_SECRET: ${{ secrets.TRANSIFEX_SECRET }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
run: scripts/transifex.sh --append-tags=main

- name: Build debug build
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh debug

- name: Run tests
if: ${{ !cancelled() }}
run: scripts/run-tests.sh

- name: Run minimal release checks
run: scripts/release-checks.sh --minimal
- name: Build release build and upload to Testflight (config=production)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:production
- name: Build release build and upload to Testflight (config=beta)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:beta
- name: Build release build and upload to Testflight (config=dev)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:dev
78 changes: 78 additions & 0 deletions .github/workflows/ios-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: ios-pr

#
# This workflow is run on all PRs (before they're merged).
#

on:
pull_request:
branches: [ main ]

env:
COMMIT_SHA: ${{ github.sha }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
TARGET_BRANCH_NAME: ${{ github.base_ref || github.ref_name }}
# Join all secrets, so that they're "used", and will be masked in logs
MASKED_SECRETS: ${{ join(secrets, '\n') }}

jobs:
build:
runs-on: macOS-13
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Show build info
env:
TEST_SECRET: ${{ secrets.MASK_TEST }}
run: scripts/show-ci-info.sh

- name: SSH setup (for cloning ekirjasto-ios-keys through Fastlane match)
uses: MrSquaare/[email protected]
with:
private-key-name: ekirjasto-ci-ed25519
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
host: github.com
- name: Force Xcode 15
run: sudo xcode-select -switch /Applications/Xcode_15.0.1.app

- name: Bootstrap (and reveal secrets)
env:
EKIRJASTO_FASTLANE_APP_STORE_CONNECT_API_KEY_JSON_BASE64: ${{ secrets.FASTLANE_APP_STORE_CONNECT_API_KEY_JSON }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
EKIRJASTO_LIBLCP_DEPENDENCY_SECRET: ${{ secrets.LIBLCP_DEPENDENCY_SECRET }}
# Carthage gets rate-limited in GitHub Actions if unauthenticated
# (they're all public repositories, so auth isn't otherwise necessary)
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: scripts/bootstrap.sh --overwrite-secrets

- name: App version and build number consistency check
run: scripts/version.sh --check

- name: Build debug build
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh debug
- name: Build release build
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release

# TODO:SAMI: Remove these steps from the PR workflow, only here for testing
- name: Build release build and upload to Testflight (config=production)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:production
- name: Build release build and upload to Testflight (config=beta)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:beta
- name: Build release build and upload to Testflight (config=dev)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:dev

- name: Run tests
if: ${{ !cancelled() }}
run: scripts/run-tests.sh
84 changes: 84 additions & 0 deletions .github/workflows/ios-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: ios-main

#
# This workflow is run for all commits in release/* branches.
#

on:
push:
branches: [ main ]

env:
COMMIT_SHA: ${{ github.sha }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
TARGET_BRANCH_NAME: ${{ github.base_ref || github.ref_name }}
# Join all secrets, so that they're "used", and will be masked in logs
MASKED_SECRETS: ${{ join(secrets, '\n') }}

jobs:
build:
runs-on: macOS-13
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Show build info
env:
TEST_SECRET: ${{ secrets.MASK_TEST }}
run: scripts/show-ci-info.sh

- name: SSH setup (for cloning ekirjasto-ios-keys through Fastlane match)
uses: MrSquaare/[email protected]
with:
private-key-name: ekirjasto-ci-ed25519
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
host: github.com
- name: Force Xcode 15
run: sudo xcode-select -switch /Applications/Xcode_15.0.1.app

- name: Bootstrap (and reveal secrets)
env:
EKIRJASTO_FASTLANE_APP_STORE_CONNECT_API_KEY_JSON_BASE64: ${{ secrets.FASTLANE_APP_STORE_CONNECT_API_KEY_JSON }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
EKIRJASTO_LIBLCP_DEPENDENCY_SECRET: ${{ secrets.LIBLCP_DEPENDENCY_SECRET }}
# Carthage gets rate limited in GitHub Actions if unauthenticated
# (they're all public repositories, so auth isn't otherwise necessary)
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: scripts/bootstrap.sh --overwrite-secrets

- name: App version and build number consistency check
run: scripts/version.sh --check

- name: Upload and download Transifex localizations
env:
EKIRJASTO_IOS_TRANSIFEX_SECRET: ${{ secrets.TRANSIFEX_SECRET }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
run: scripts/transifex.sh --append-tags=release

- name: Build debug build
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh debug

- name: Run tests
if: ${{ !cancelled() }}
run: scripts/run-tests.sh

- name: Run release checks
env:
EKIRJASTO_IOS_TRANSIFEX_SECRET: ${{ secrets.TRANSIFEX_SECRET }}
EKIRJASTO_IOS_TRANSIFEX_TOKEN: ${{ secrets.TRANSIFEX_TOKEN }}
run: scripts/release-checks.sh
- name: Build release build and upload to Testflight (config=production)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:production
- name: Build release build and upload to Testflight (config=beta)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:beta
- name: Build release build and upload to Testflight (config=dev)
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: scripts/build.sh release_upload config:dev
18 changes: 17 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,24 @@ adobe-rmsdk
**/ReaderClientCert.sig
**/APIKeys.swift
Carthage*
**/GoogleService-Info.plist
#**/GoogleService-Info.plist
**/TPPSecrets.swift
fastlane/report.xml
fastlane/*_output
Palace.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

# Ignore temporary files
temp/

# Ignore Cartfile and Carfile.resolved (the bootstrap script copies them into
# place, and they can contain a liblcp secret, so they shouldn't be committed)
Cartfile
Cartfile.resolved

# Ignore build files
*.dSYM.zip
*.ipa

# Ignore txios-cli (Transifex CLI tool), it's auto-downloaded and built
txios-cli

File renamed without changes.
File renamed without changes.
Loading

0 comments on commit d44d450

Please sign in to comment.