Skip to content

Patch and Release OTA #3060

Patch and Release OTA

Patch and Release OTA #3060

Workflow file for this run

name: Patch and Release OTA
on:
schedule:
- cron: "0 */6 * * *" # Check for update every 6 hours (UTC). GrapheneOS checks every 6 hours.
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
device-id:
description: Device code name
required: true
root:
description: Add root to the build
required: false
type: boolean
default: false
magisk-preinit-device:
description: Magisk preinit device. For example, "sda8", "sda15" etc.,
required: false
update-channel:
description: GrapheneOS update channel. Supports `alpha`, `beta` and `stable`. Defaults to `stable`
required: false
release-type:
description: "How to handle the release. `default`: build and publish if new. `build-only`: only build. `force-publish`: build and publish even if it exists."
required: true
type: choice
options:
- default
- build-only
- force-publish
default: default
# Allows this workflow to be called per device, see multi-release.yml
workflow_call:
inputs:
device-id:
required: true
type: string
root:
required: false
type: boolean
default: false
magisk-preinit-device:
required: false
type: string
update-channel:
required: false
type: string
release-type:
required: false
type: string
default: default
env:
CARGO_INCREMENTAL: 1
DEVICE_NAME: ${{ inputs.device-id }}
INTERACTIVE_MODE: false
GRAPHENEOS_UPDATE_CHANNEL: ${{ inputs.update-channel }}
RUST_BACKTRACE: short
RUSTUP_MAX_RETRIES: 10
jobs:
build:
runs-on: ubuntu-latest
# Required by publisher step
permissions: write-all
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
# Allow for switching to github-pages branch
fetch-depth: 0
- name: Read from `env.toml` if exist
if: ${{ github.event_name == 'schedule' }}
run: |
# Check if the file exists
source src/util_functions.sh && check_toml_env
echo "DEVICE_NAME=${DEVICE_NAME}" >> $GITHUB_ENV
echo "GRAPHENEOS_UPDATE_CHANNEL=${GRAPHENEOS[UPDATE_CHANNEL]}" >> $GITHUB_ENV
echo "FORCE_UPDATE=${FORCE_UPDATE:-false}" >> $GITHUB_ENV
# Let scheduled runs build rooted OTAs when env.toml enables it
echo "ROOT=${ADDITIONALS[ROOT]}" >> $GITHUB_ENV
echo "MAGISK_PREINIT=${MAGISK[PREINIT]}" >> $GITHUB_ENV
- name: Check if `magisk-preinit-device` is set when `root` is true
run: |
# Inputs win on manual runs, env.toml supplies the values on schedule
root="${{ inputs.root || env.ROOT }}"
magisk_preinit_device="${{ inputs.magisk-preinit-device || env.MAGISK_PREINIT }}"
# Ensure that the boolean comparison is correctly handled
if [ "$root" == "true" ] && [ -z "$magisk_preinit_device" ]; then
echo -e "::error:: magisk-preinit-device is required when root is true."
exit 1
fi
- name: Set GrapheneOS version
shell: bash
run: |
# Device name is a required parameter
if [[ -z "${DEVICE_NAME}" ]]; then
echo -e "::error::Missing required param \`DEVICE_NAME\`"
exit 1
fi
# Fetch the latest GrapheneOS version and set up the environment
source src/fetcher.sh && get_latest_version
echo "GRAPHENEOS_VERSION=${VERSION[GRAPHENEOS]}" >> $GITHUB_ENV
- name: Check if a build exists already and verify assets
shell: bash
if: github.event_name == 'schedule' || inputs.release-type == 'default'
env:
REPOSITORY: ${{ github.repository }}
ROOT: ${{ inputs.root || env.ROOT }}
run: src/ci/check_existing_build.sh
- name: Setup Git
env:
USER_EMAIL: ${{ secrets.EMAIL }}
USER_NAME: ${{ github.repository_owner }}
run: |
git config --global user.email "$USER_EMAIL"
git config --global user.name "$USER_NAME"
- name: Install Rust stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable 2 weeks ago
- name: Build and Cache Rust Dependencies
uses: Swatinem/rust-cache@v2.9.2
- name: Install Python
uses: actions/setup-python@v7
with:
python-version: "3.12-dev"
- name: Setup Environment variables
run: |
echo "KEYS_AVB_BASE64<<EOF" >> $GITHUB_ENV
echo "${{ secrets.AVB_KEY }}" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "KEYS_CERT_OTA_BASE64<<EOF" >> $GITHUB_ENV
echo "${{ secrets.CERT_OTA }}" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "KEYS_OTA_BASE64<<EOF" >> $GITHUB_ENV
echo "${{ secrets.OTA_KEY }}" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Patch OTA
shell: bash
env:
ADDITIONALS_ROOT: ${{ inputs.root || env.ROOT }}
CLEANUP: true
MAGISK_PREINIT: ${{ inputs.magisk-preinit-device || env.MAGISK_PREINIT }}
PASSPHRASE_AVB: ${{ secrets.PASSPHRASE_AVB }}
PASSPHRASE_OTA: ${{ secrets.PASSPHRASE_OTA }}
run: |
echo -e "Running release script.."
# Instead of running the script directly,
# we source it to get the variables in the current shell and use them in the next steps by exporting them
. src/main.sh
# Export the variables for the next steps
echo "GRAPHENEOS_OTA_TARGET=${GRAPHENEOS[OTA_TARGET]}" >> $GITHUB_ENV
echo "OUTPUTS_PATCHED_OTA=${OUTPUTS[PATCHED_OTA]}" >> $GITHUB_ENV
echo "WORKDIR=${WORKDIR}" >> $GITHUB_ENV
- name: Generate Changelog
run: |
# Generate a changelog for the release taking the latest GrapheneOS release
echo -e "See [Changelog](https://grapheneos.org/releases#${{ env.GRAPHENEOS_VERSION }})." > ${{ github.workspace }}-CHANGELOG.txt
- name: Make Release
uses: softprops/action-gh-release@v3
if: inputs.release-type != 'build-only'
with:
body_path: ${{ github.workspace }}-CHANGELOG.txt
files: |
${{ env.OUTPUTS_PATCHED_OTA }}
${{ env.OUTPUTS_PATCHED_OTA }}.csig
name: "${{ env.GRAPHENEOS_VERSION }}"
tag_name: "${{ env.GRAPHENEOS_VERSION }}"
- name: Remove superseded release assets
shell: bash
if: env.FORCE_REBUILD == 'true' && inputs.release-type != 'build-only'
env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
ROOT: ${{ inputs.root || env.ROOT }}
run: src/ci/remove_superseded_assets.sh
- name: Publish OTA to server
shell: bash
if: inputs.release-type != 'build-only'
env:
RELEASE_TYPE: ${{ inputs.release-type }}
ROOT: ${{ inputs.root || env.ROOT }}
run: src/ci/publish_ota.sh