Change github remote url #137
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: MatrixOS Build and Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| inputs: | |
| channel: | |
| description: Release channel to build and publish | |
| required: true | |
| type: choice | |
| default: release | |
| options: | |
| - release | |
| - rc | |
| - beta | |
| - nightly | |
| - development | |
| release_ver: | |
| description: RC/Beta number in the range 1-31. Ignored for release, nightly, and development. | |
| required: false | |
| type: string | |
| default: '1' | |
| tag_name: | |
| description: Optional GitHub release tag override | |
| required: false | |
| type: string | |
| release_name: | |
| description: Optional GitHub release title override | |
| required: false | |
| type: string | |
| publish: | |
| description: Publish GitHub Release assets | |
| required: true | |
| type: boolean | |
| default: true | |
| permissions: | |
| contents: write | |
| env: | |
| ESP_IDF_VERSION: v5.3.4 | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| asset_suffix: ${{ steps.meta.outputs.asset_suffix }} | |
| base_version: ${{ steps.meta.outputs.base_version }} | |
| build_target: ${{ steps.meta.outputs.build_target }} | |
| channel: ${{ steps.meta.outputs.channel }} | |
| channel_label: ${{ steps.meta.outputs.channel_label }} | |
| channel_slug: ${{ steps.meta.outputs.channel_slug }} | |
| commit_short: ${{ steps.meta.outputs.commit_short }} | |
| display_version: ${{ steps.meta.outputs.display_version }} | |
| generated_at: ${{ steps.meta.outputs.generated_at }} | |
| prerelease: ${{ steps.meta.outputs.prerelease }} | |
| publish: ${{ steps.meta.outputs.publish }} | |
| release_date: ${{ steps.meta.outputs.release_date }} | |
| release_name: ${{ steps.meta.outputs.release_name }} | |
| release_tag: ${{ steps.meta.outputs.release_tag }} | |
| release_ver: ${{ steps.meta.outputs.release_ver }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Compute release metadata | |
| id: meta | |
| shell: bash | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| INPUT_CHANNEL: ${{ github.event.inputs.channel || '' }} | |
| INPUT_PUBLISH: ${{ github.event.inputs.publish || '' }} | |
| INPUT_RELEASE_NAME: ${{ github.event.inputs.release_name || '' }} | |
| INPUT_RELEASE_VER: ${{ github.event.inputs.release_ver || '' }} | |
| INPUT_TAG_NAME: ${{ github.event.inputs.tag_name || '' }} | |
| run: | | |
| set -euo pipefail | |
| append_output() { | |
| local key="$1" | |
| local value="$2" | |
| local delimiter="EOF_$(date +%s%N)_$RANDOM" | |
| { | |
| printf '%s<<%s\n' "$key" "$delimiter" | |
| printf '%s\n' "$value" | |
| printf '%s\n' "$delimiter" | |
| } >> "$GITHUB_OUTPUT" | |
| } | |
| validate_release_ver() { | |
| local value="$1" | |
| local channel_name="$2" | |
| if [[ -z "$value" ]]; then | |
| printf '1\n' | |
| return | |
| fi | |
| if [[ ! "$value" =~ ^[0-9]+$ ]]; then | |
| echo "workflow_dispatch.release_ver must be an integer in the range 1-31 for ${channel_name} builds" >&2 | |
| exit 1 | |
| fi | |
| local normalized=$((10#$value)) | |
| if (( normalized < 1 || normalized > 31 )); then | |
| echo "workflow_dispatch.release_ver must be in the range 1-31 for ${channel_name} builds" >&2 | |
| exit 1 | |
| fi | |
| printf '%s\n' "$normalized" | |
| } | |
| major=$(awk '/^#define MATRIXOS_MAJOR_VER / {print $3}' OS/System/Parameters.h) | |
| minor=$(awk '/^#define MATRIXOS_MINOR_VER / {print $3}' OS/System/Parameters.h) | |
| patch=$(awk '/^#define MATRIXOS_PATCH_VER / {print $3}' OS/System/Parameters.h) | |
| commit_short=$(git rev-parse --short=8 HEAD) | |
| release_date=$(date -u +'%Y-%m-%d') | |
| date_compact=$(date -u +'%Y%m%d') | |
| generated_at=$(date -u +'%Y-%m-%dT%H:%M:%SZ') | |
| display_version="${major}.${minor}" | |
| if [[ "$patch" != "0" ]]; then | |
| display_version="${display_version}.${patch}" | |
| fi | |
| base_version="v${major}.${minor}.${patch}" | |
| if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then | |
| channel="$INPUT_CHANNEL" | |
| publish="$INPUT_PUBLISH" | |
| elif [[ "$EVENT_NAME" == "push" ]]; then | |
| channel="nightly" | |
| publish="true" | |
| else | |
| channel="nightly" | |
| publish="false" | |
| fi | |
| case "$channel" in | |
| release) | |
| build_target="build-release" | |
| channel_label="Release" | |
| channel_slug="release" | |
| prerelease="false" | |
| release_ver="0" | |
| default_tag="$base_version" | |
| default_name="Matrix OS ${display_version} Release" | |
| ;; | |
| rc) | |
| build_target="build-rc" | |
| channel_label="Release Candidate" | |
| channel_slug="rc" | |
| prerelease="true" | |
| release_ver=$(validate_release_ver "${INPUT_RELEASE_VER:-}" "rc") | |
| default_tag="${base_version}-rc.${release_ver}" | |
| default_name="Matrix OS ${display_version} RC ${release_ver}" | |
| ;; | |
| beta) | |
| build_target="build-beta" | |
| channel_label="Beta" | |
| channel_slug="beta" | |
| prerelease="true" | |
| release_ver=$(validate_release_ver "${INPUT_RELEASE_VER:-}" "beta") | |
| default_tag="${base_version}-beta.${release_ver}" | |
| default_name="Matrix OS ${display_version} Beta ${release_ver}" | |
| ;; | |
| nightly) | |
| build_target="build-nightly" | |
| channel_label="Nightly" | |
| channel_slug="nightly" | |
| prerelease="true" | |
| release_ver="0" | |
| default_tag="nightly-${date_compact}-${commit_short}" | |
| default_name="Matrix OS ${display_version} Nightly ${release_date} ${commit_short}" | |
| ;; | |
| development) | |
| build_target="build-dev" | |
| channel_label="InDev" | |
| channel_slug="indev" | |
| prerelease="true" | |
| release_ver="0" | |
| default_tag="indev-${date_compact}-${commit_short}" | |
| default_name="Matrix OS ${display_version} InDev ${release_date} ${commit_short}" | |
| ;; | |
| *) | |
| echo "Unsupported channel: $channel" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| release_tag="${INPUT_TAG_NAME:-$default_tag}" | |
| release_name="${INPUT_RELEASE_NAME:-$default_name}" | |
| if ! git check-ref-format --allow-onelevel "refs/tags/$release_tag" >/dev/null 2>&1; then | |
| echo "Invalid release tag: $release_tag" >&2 | |
| exit 1 | |
| fi | |
| asset_suffix=$(printf '%s' "$release_tag" | tr -cs 'A-Za-z0-9._-' '-') | |
| asset_suffix=$(printf '%s' "$asset_suffix" | sed 's/^-*//; s/-*$//') | |
| if [[ -z "$asset_suffix" ]]; then | |
| asset_suffix="matrixos-${channel_slug}-${commit_short}" | |
| fi | |
| append_output "asset_suffix" "$asset_suffix" | |
| append_output "base_version" "$base_version" | |
| append_output "build_target" "$build_target" | |
| append_output "channel" "$channel" | |
| append_output "channel_label" "$channel_label" | |
| append_output "channel_slug" "$channel_slug" | |
| append_output "commit_short" "$commit_short" | |
| append_output "display_version" "$display_version" | |
| append_output "generated_at" "$generated_at" | |
| append_output "prerelease" "$prerelease" | |
| append_output "publish" "$publish" | |
| append_output "release_date" "$release_date" | |
| append_output "release_name" "$release_name" | |
| append_output "release_tag" "$release_tag" | |
| append_output "release_ver" "$release_ver" | |
| build-firmware: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| device: | |
| - Mystrix1 | |
| - Mystrix2 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Build ${{ matrix.device }} UF2 | |
| uses: espressif/esp-idf-ci-action@v1 | |
| with: | |
| esp_idf_version: ${{ env.ESP_IDF_VERSION }} | |
| target: esp32s3 | |
| path: . | |
| command: >- | |
| make DEVICE=${{ matrix.device }} FAMILY=${{ matrix.device }} | |
| RELEASE_VER=${{ needs.prepare.outputs.release_ver }} | |
| fullclean ${{ needs.prepare.outputs.build_target }} uf2 | |
| - name: Package ${{ matrix.device }} release artifact | |
| shell: bash | |
| env: | |
| ASSET_SUFFIX: ${{ needs.prepare.outputs.asset_suffix }} | |
| DEVICE: ${{ matrix.device }} | |
| run: | | |
| set -euo pipefail | |
| sudo chown -R "$(id -u):$(id -g)" build | |
| mkdir -p out | |
| source_file="build/${DEVICE}/MatrixOS-${DEVICE}.uf2" | |
| asset_name="MatrixOS-${DEVICE}-${ASSET_SUFFIX}.uf2" | |
| cp "$source_file" "out/$asset_name" | |
| - name: Upload ${{ matrix.device }} artifact bundle | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-${{ matrix.device }} | |
| path: out/* | |
| if-no-files-found: error | |
| build-sil: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install WebUI dependencies | |
| working-directory: Devices/MystrixSim/WebUI | |
| run: npm ci | |
| - name: Install MystrixSim build dependencies | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if command -v sudo >/dev/null 2>&1; then | |
| sudo apt-get update | |
| sudo apt-get install -y cmake make zip | |
| else | |
| apt-get update | |
| apt-get install -y cmake make zip | |
| fi | |
| - name: Install Emscripten SDK | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| git clone https://github.com/emscripten-core/emsdk.git "$RUNNER_TEMP/emsdk" | |
| pushd "$RUNNER_TEMP/emsdk" | |
| ./emsdk install 4.0.12 | |
| ./emsdk activate 4.0.12 | |
| popd | |
| - name: Build MystrixSim runtime | |
| shell: bash | |
| env: | |
| BUILD_TARGET: ${{ needs.prepare.outputs.build_target }} | |
| RELEASE_VER: ${{ needs.prepare.outputs.release_ver }} | |
| run: | | |
| set -euo pipefail | |
| source "$RUNNER_TEMP/emsdk/emsdk_env.sh" | |
| export CMAKE="$(command -v cmake)" | |
| export EMCMAKE="$(command -v emcmake)" | |
| "$CMAKE" --version | |
| make DEVICE=MystrixSim FAMILY=MystrixSim fullclean | |
| make DEVICE=MystrixSim FAMILY=MystrixSim RELEASE_VER="$RELEASE_VER" "$BUILD_TARGET" | |
| - name: Package MystrixSim release bundle | |
| shell: bash | |
| env: | |
| ASSET_SUFFIX: ${{ needs.prepare.outputs.asset_suffix }} | |
| run: | | |
| set -euo pipefail | |
| mkdir -p out | |
| package_asset="MatrixOS-MystrixSim-${ASSET_SUFFIX}.msfw" | |
| zip -j -q "out/$package_asset" \ | |
| "build/MystrixSim/Devices/MystrixSim/MatrixOSHost.js" \ | |
| "build/MystrixSim/Devices/MystrixSim/MatrixOSHost.wasm" | |
| - name: Upload MystrixSim artifact bundle | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-MystrixSim | |
| path: out/* | |
| if-no-files-found: error | |
| build-firmware-dev: | |
| if: needs.prepare.outputs.channel == 'nightly' || (needs.prepare.outputs.publish != 'true' && needs.prepare.outputs.channel != 'development') | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| device: | |
| - Mystrix1 | |
| - Mystrix2 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Build ${{ matrix.device }} InDev UF2 | |
| uses: espressif/esp-idf-ci-action@v1 | |
| with: | |
| esp_idf_version: ${{ env.ESP_IDF_VERSION }} | |
| target: esp32s3 | |
| path: . | |
| command: >- | |
| make DEVICE=${{ matrix.device }} FAMILY=${{ matrix.device }} | |
| fullclean build-dev uf2 | |
| - name: Package ${{ matrix.device }} InDev artifact | |
| shell: bash | |
| env: | |
| COMMIT_SHORT: ${{ needs.prepare.outputs.commit_short }} | |
| RELEASE_DATE: ${{ needs.prepare.outputs.release_date }} | |
| DEVICE: ${{ matrix.device }} | |
| run: | | |
| set -euo pipefail | |
| sudo chown -R "$(id -u):$(id -g)" build | |
| mkdir -p out | |
| source_file="build/${DEVICE}/MatrixOS-${DEVICE}.uf2" | |
| asset_name="MatrixOS-${DEVICE}-indev-${RELEASE_DATE}-${COMMIT_SHORT}.uf2" | |
| cp "$source_file" "out/$asset_name" | |
| - name: Upload ${{ matrix.device }} InDev artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: indev-${{ matrix.device }} | |
| path: out/* | |
| if-no-files-found: error | |
| build-sil-dev: | |
| if: needs.prepare.outputs.channel == 'nightly' || (needs.prepare.outputs.publish != 'true' && needs.prepare.outputs.channel != 'development') | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install WebUI dependencies | |
| working-directory: Devices/MystrixSim/WebUI | |
| run: npm ci | |
| - name: Install MystrixSim build dependencies | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if command -v sudo >/dev/null 2>&1; then | |
| sudo apt-get update | |
| sudo apt-get install -y cmake make zip | |
| else | |
| apt-get update | |
| apt-get install -y cmake make zip | |
| fi | |
| - name: Install Emscripten SDK | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| git clone https://github.com/emscripten-core/emsdk.git "$RUNNER_TEMP/emsdk" | |
| pushd "$RUNNER_TEMP/emsdk" | |
| ./emsdk install 4.0.12 | |
| ./emsdk activate 4.0.12 | |
| popd | |
| - name: Build MystrixSim InDev runtime | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| source "$RUNNER_TEMP/emsdk/emsdk_env.sh" | |
| export CMAKE="$(command -v cmake)" | |
| export EMCMAKE="$(command -v emcmake)" | |
| "$CMAKE" --version | |
| make DEVICE=MystrixSim FAMILY=MystrixSim fullclean | |
| make DEVICE=MystrixSim FAMILY=MystrixSim build-dev | |
| - name: Package MystrixSim InDev artifact bundle | |
| shell: bash | |
| env: | |
| COMMIT_SHORT: ${{ needs.prepare.outputs.commit_short }} | |
| RELEASE_DATE: ${{ needs.prepare.outputs.release_date }} | |
| run: | | |
| set -euo pipefail | |
| mkdir -p out | |
| package_asset="MatrixOS-MystrixSim-indev-${RELEASE_DATE}-${COMMIT_SHORT}.msfw" | |
| zip -j -q "out/$package_asset" \ | |
| "build/MystrixSim/Devices/MystrixSim/MatrixOSHost.js" \ | |
| "build/MystrixSim/Devices/MystrixSim/MatrixOSHost.wasm" | |
| - name: Upload MystrixSim InDev artifact bundle | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: indev-MystrixSim | |
| path: out/* | |
| if-no-files-found: error | |
| publish-release: | |
| if: ${{ always() && needs.prepare.outputs.publish == 'true' && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} | |
| needs: | |
| - prepare | |
| - build-firmware | |
| - build-sil | |
| - build-firmware-dev | |
| - build-sil-dev | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Download build bundles | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: release-* | |
| path: artifacts | |
| - name: Download InDev bundles | |
| if: needs.prepare.outputs.channel == 'nightly' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: indev-* | |
| path: artifacts | |
| - name: Collect release files and metadata | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p release-files | |
| find artifacts -type f \( -name '*.uf2' -o -name '*.msfw' -o -name '*.mspkg' \) -exec cp {} release-files/ \; | |
| - name: Generate release index | |
| shell: bash | |
| env: | |
| BASE_VERSION: ${{ needs.prepare.outputs.base_version }} | |
| COMMIT_SHORT: ${{ needs.prepare.outputs.commit_short }} | |
| DISPLAY_VERSION: ${{ needs.prepare.outputs.display_version }} | |
| GENERATED_AT: ${{ needs.prepare.outputs.generated_at }} | |
| PRERELEASE: ${{ needs.prepare.outputs.prerelease }} | |
| RELEASE_DATE: ${{ needs.prepare.outputs.release_date }} | |
| RELEASE_NAME: ${{ needs.prepare.outputs.release_name }} | |
| RELEASE_TAG: ${{ needs.prepare.outputs.release_tag }} | |
| CHANNEL_LABEL: ${{ needs.prepare.outputs.channel_label }} | |
| CHANNEL_SLUG: ${{ needs.prepare.outputs.channel_slug }} | |
| ASSET_SUFFIX: ${{ needs.prepare.outputs.asset_suffix }} | |
| run: | | |
| set -euo pipefail | |
| channel_prefix=$(printf '%s' "$CHANNEL_SLUG" | tr '[:lower:]' '[:upper:]') | |
| export INDEX_OUTPUT="release-files/index.json" | |
| export INDEX_TAG="$RELEASE_TAG" | |
| export INDEX_NAME="$RELEASE_NAME" | |
| export INDEX_CHANNEL="$CHANNEL_LABEL" | |
| export INDEX_CHANNEL_SLUG="$CHANNEL_SLUG" | |
| export INDEX_VERSION="$BASE_VERSION" | |
| export INDEX_DISPLAY_VERSION="Matrix OS ${DISPLAY_VERSION}" | |
| export INDEX_DATE="$RELEASE_DATE" | |
| export INDEX_GENERATED_AT="$GENERATED_AT" | |
| export INDEX_COMMIT="$COMMIT_SHORT" | |
| export INDEX_PRERELEASE="$PRERELEASE" | |
| export "INDEX_${channel_prefix}_MYSTRIX1_FILES=MatrixOS-Mystrix1-${ASSET_SUFFIX}.uf2" | |
| export "INDEX_${channel_prefix}_MYSTRIX2_FILES=MatrixOS-Mystrix2-${ASSET_SUFFIX}.uf2" | |
| export "INDEX_${channel_prefix}_MYSTRIXSIM_FILES=MatrixOS-MystrixSim-${ASSET_SUFFIX}.msfw" | |
| if [[ "$CHANNEL_SLUG" == "nightly" ]]; then | |
| export INDEX_INDEV_MYSTRIX1_FILES="MatrixOS-Mystrix1-indev-${RELEASE_DATE}-${COMMIT_SHORT}.uf2" | |
| export INDEX_INDEV_MYSTRIX2_FILES="MatrixOS-Mystrix2-indev-${RELEASE_DATE}-${COMMIT_SHORT}.uf2" | |
| export INDEX_INDEV_MYSTRIXSIM_FILES="MatrixOS-MystrixSim-indev-${RELEASE_DATE}-${COMMIT_SHORT}.msfw" | |
| fi | |
| NODE_BIN="${EMSDK_NODE:-$(command -v nodejs 2>/dev/null || command -v node 2>/dev/null)}" | |
| if [[ -z "$NODE_BIN" ]]; then | |
| echo "Node.js is required to generate release metadata." >&2 | |
| exit 1 | |
| fi | |
| "$NODE_BIN" Tools/release/write-device-metadata.mjs | |
| - name: Create or update GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.release_tag }} | |
| name: ${{ needs.prepare.outputs.release_name }} | |
| target_commitish: ${{ github.sha }} | |
| prerelease: ${{ needs.prepare.outputs.prerelease == 'true' }} | |
| fail_on_unmatched_files: true | |
| files: | | |
| release-files/* | |
| body: | | |
| Channel: ${{ needs.prepare.outputs.channel_label }} | |
| Commit: ${{ needs.prepare.outputs.commit_short }} | |
| Generated at: ${{ needs.prepare.outputs.generated_at }} |