Release #47
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version, e.g. 0.1.0" | |
| required: true | |
| type: string | |
| channel: | |
| description: "Update channel" | |
| required: true | |
| default: "stable" | |
| type: choice | |
| options: | |
| - stable | |
| - beta | |
| - alpha | |
| prerelease: | |
| description: "Publish as prerelease" | |
| required: true | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-natives: | |
| name: native ${{ matrix.label }} | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| include: | |
| - label: linux-x64 | |
| runner: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| lib: librapier_moud.so | |
| - label: linux-arm64 | |
| runner: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| lib: librapier_moud.so | |
| apt: gcc-aarch64-linux-gnu | |
| linker: aarch64-linux-gnu-gcc | |
| - label: windows-x64 | |
| runner: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| lib: rapier_moud.dll | |
| - label: macos-x64 | |
| runner: macos-14 | |
| target: x86_64-apple-darwin | |
| lib: librapier_moud.dylib | |
| - label: macos-arm64 | |
| runner: macos-14 | |
| target: aarch64-apple-darwin | |
| lib: librapier_moud.dylib | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: install rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: install cross-linker (linux-arm64) | |
| if: matrix.apt != '' | |
| run: sudo apt-get update && sudo apt-get install -y ${{ matrix.apt }} | |
| - name: configure linker (linux-arm64) | |
| if: matrix.linker != '' | |
| run: | | |
| mkdir -p .cargo | |
| printf '[target.%s]\nlinker = "%s"\n' "${{ matrix.target }}" "${{ matrix.linker }}" > .cargo/config.toml | |
| working-directory: physics-natives | |
| - name: cargo build | |
| run: cargo build --release --target ${{ matrix.target }} | |
| working-directory: physics-natives | |
| - name: upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: native-${{ matrix.label }} | |
| path: physics-natives/target/${{ matrix.target }}/release/${{ matrix.lib }} | |
| if-no-files-found: error | |
| build-release: | |
| needs: build-natives | |
| runs-on: ubuntu-latest | |
| environment: Production | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download native artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: native-artifacts | |
| - name: Stage native binaries into physics-rapier | |
| shell: bash | |
| run: | | |
| set -eux | |
| stage() { | |
| local label="$1" lib="$2" dir="$3" | |
| install -Dm755 "native-artifacts/native-${label}/${lib}" \ | |
| "physics-rapier/src/main/resources/natives/${dir}/${lib}" | |
| } | |
| stage linux-x64 librapier_moud.so linux-x64 | |
| stage linux-arm64 librapier_moud.so linux-arm64 | |
| stage windows-x64 rapier_moud.dll windows-x64 | |
| stage macos-x64 librapier_moud.dylib macos-x64 | |
| stage macos-arm64 librapier_moud.dylib macos-arm64 | |
| - name: Set up Java 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: "25-ea" | |
| - name: Set up Java 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: "21" | |
| cache: gradle | |
| - name: Make Gradle executable | |
| run: chmod +x ./gradlew | |
| - name: Install vendored libs to mavenLocal | |
| shell: bash | |
| run: | | |
| for spec in "com/miry/miry:libs/miry-1.0-SNAPSHOT.jar:1.0-SNAPSHOT" \ | |
| "fr/mrqsdf/BbModelReader:libs/BbModelReader-1.0-SNAPSHOT.jar:1.0-SNAPSHOT" \ | |
| "moud/vendored/luau-natives-windows-x64:libs/luau-natives-windows-x64-1.0.0-moud.jar:1.0.0"; do | |
| IFS=: read -r coords jar version <<< "$spec" | |
| group="${coords%/*}" | |
| artifact="${coords##*/}" | |
| dest="$HOME/.m2/repository/${coords}/${version}" | |
| mkdir -p "$dest" | |
| cp "$jar" "$dest/${artifact}-${version}.jar" | |
| cat > "$dest/${artifact}-${version}.pom" <<POMEOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <project xmlns="http://maven.apache.org/POM/4.0.0"><modelVersion>4.0.0</modelVersion> | |
| <groupId>${group//\//.}</groupId><artifactId>${artifact}</artifactId><version>${version}</version> | |
| </project> | |
| POMEOF | |
| done | |
| - name: Resolve release metadata | |
| id: meta | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]]; then | |
| TAG="${GITHUB_REF_NAME}" | |
| VERSION="${TAG#v}" | |
| CHANNEL="stable" | |
| PRERELEASE="false" | |
| else | |
| VERSION="${{ inputs.version }}" | |
| VERSION="${VERSION#v}" | |
| TAG="v${VERSION}" | |
| CHANNEL="${{ inputs.channel }}" | |
| PRERELEASE="${{ inputs.prerelease }}" | |
| fi | |
| echo "tag=${TAG}" >> "$GITHUB_OUTPUT" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "channel=${CHANNEL}" >> "$GITHUB_OUTPUT" | |
| echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT" | |
| - name: Build artifacts | |
| run: | | |
| ./gradlew \ | |
| :moud-bootstrap:remapJar \ | |
| :client-launcher:shadowJar \ | |
| :client-fabric:remapRuntimeJar \ | |
| :server-minestom:shadowJar \ | |
| :server-supervisor:shadowJar \ | |
| -Pmoud.server.enableLuau=true \ | |
| -Pmoud.server.java=25 | |
| - name: Package release archives | |
| id: package | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${{ steps.meta.outputs.version }}" | |
| TAG="${{ steps.meta.outputs.tag }}" | |
| CLIENT_JAR="$(find client-fabric/build/libs -maxdepth 1 -type f -name '*-runtime.jar' ! -name '*-sources.jar' | sort | head -n1)" | |
| BOOTSTRAP_JAR="$(find moud-bootstrap/build/libs -maxdepth 1 -type f -name '*.jar' ! -name '*-sources.jar' | sort | head -n1)" | |
| CLIENT_LAUNCHER_JAR="$(find client-launcher/build/libs -maxdepth 1 -type f -name '*.jar' ! -name '*-sources.jar' | sort | head -n1)" | |
| SERVER_JAR="$(find server-minestom/build/libs -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' ! -name '*-sources.jar' | sort | head -n1)" | |
| SUPERVISOR_JAR="$(find server-supervisor/build/libs -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' ! -name '*-sources.jar' | sort | head -n1)" | |
| if [[ -z "${CLIENT_JAR}" || ! -f "${CLIENT_JAR}" ]]; then | |
| echo "Client jar not found" >&2; exit 1 | |
| fi | |
| if [[ -z "${BOOTSTRAP_JAR}" || ! -f "${BOOTSTRAP_JAR}" ]]; then | |
| echo "Bootstrap jar not found" >&2; exit 1 | |
| fi | |
| if [[ -z "${CLIENT_LAUNCHER_JAR}" || ! -f "${CLIENT_LAUNCHER_JAR}" ]]; then | |
| echo "Client launcher jar not found" >&2; exit 1 | |
| fi | |
| if [[ -z "${SERVER_JAR}" || ! -f "${SERVER_JAR}" ]]; then | |
| echo "Server jar not found" >&2; exit 1 | |
| fi | |
| rm -rf dist | |
| mkdir -p dist/stage/client/engine/mods | |
| mkdir -p dist/stage/server/engine | |
| cp "${CLIENT_JAR}" "dist/stage/client/engine/mods/moud-client.jar" | |
| cp "${SERVER_JAR}" "dist/stage/server/engine/moud-server.jar" | |
| printf '%s\n' "${VERSION}" > dist/stage/client/engine/VERSION | |
| printf '%s\n' "${VERSION}" > dist/stage/server/engine/VERSION | |
| printf '%s\n' "${TAG}" > dist/stage/client/engine/RELEASE_TAG | |
| printf '%s\n' "${TAG}" > dist/stage/server/engine/RELEASE_TAG | |
| CLIENT_ARCHIVE="moud-client-${VERSION}.tar.gz" | |
| SERVER_ARCHIVE="moud-server-${VERSION}.tar.gz" | |
| tar --sort=name --mtime='UTC 2024-01-01' --owner=0 --group=0 --numeric-owner \ | |
| -C dist/stage/client -czf "dist/${CLIENT_ARCHIVE}" engine | |
| tar --sort=name --mtime='UTC 2024-01-01' --owner=0 --group=0 --numeric-owner \ | |
| -C dist/stage/server -czf "dist/${SERVER_ARCHIVE}" engine | |
| echo "client_archive=${CLIENT_ARCHIVE}" >> "$GITHUB_OUTPUT" | |
| echo "server_archive=${SERVER_ARCHIVE}" >> "$GITHUB_OUTPUT" | |
| cp "${BOOTSTRAP_JAR}" "dist/moud-bootstrap-${VERSION}.jar" | |
| echo "bootstrap_jar=moud-bootstrap-${VERSION}.jar" >> "$GITHUB_OUTPUT" | |
| cp "${CLIENT_LAUNCHER_JAR}" "dist/moud-client-launcher-${VERSION}.jar" | |
| echo "client_launcher_jar=moud-client-launcher-${VERSION}.jar" >> "$GITHUB_OUTPUT" | |
| if [[ -n "${SUPERVISOR_JAR}" && -f "${SUPERVISOR_JAR}" ]]; then | |
| cp "${SUPERVISOR_JAR}" "dist/moud-supervisor-${VERSION}.jar" | |
| echo "supervisor_jar=moud-supervisor-${VERSION}.jar" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate signed release metadata | |
| shell: bash | |
| env: | |
| RELEASE_SIGNING_PRIVATE_KEY: ${{ secrets.MOUD_RELEASE_SIGNING_PRIVATE_KEY }} | |
| run: | | |
| set -euo pipefail | |
| if [[ -z "${RELEASE_SIGNING_PRIVATE_KEY:-}" ]]; then | |
| echo "Missing secret MOUD_RELEASE_SIGNING_PRIVATE_KEY" >&2 | |
| exit 1 | |
| fi | |
| VERSION="${{ steps.meta.outputs.version }}" | |
| CHANNEL="${{ steps.meta.outputs.channel }}" | |
| TAG="${{ steps.meta.outputs.tag }}" | |
| BASE_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}" | |
| python3 tools/release_manifest.py \ | |
| --version "${VERSION}" \ | |
| --channel "${CHANNEL}" \ | |
| --base-download-url "${BASE_URL}" \ | |
| --client-archive "dist/${{ steps.package.outputs.client_archive }}" \ | |
| --server-archive "dist/${{ steps.package.outputs.server_archive }}" \ | |
| --output "dist/release.json" | |
| echo "${RELEASE_SIGNING_PRIVATE_KEY}" | base64 -d > dist/release-key.pem | |
| openssl pkey -in dist/release-key.pem -noout 2>/dev/null || { | |
| echo "Invalid private key — store the PEM file as base64 in the secret" >&2 | |
| exit 1 | |
| } | |
| openssl pkeyutl -sign -rawin -inkey dist/release-key.pem -in dist/release.json -out dist/release.sig.bin | |
| base64 -w0 dist/release.sig.bin > dist/release.sig | |
| rm -f dist/release-key.pem dist/release.sig.bin | |
| - name: Create GitHub release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.meta.outputs.tag }} | |
| name: Moud ${{ steps.meta.outputs.version }} | |
| draft: false | |
| prerelease: ${{ steps.meta.outputs.prerelease == 'true' }} | |
| generate_release_notes: true | |
| files: | | |
| dist/${{ steps.package.outputs.client_archive }} | |
| dist/${{ steps.package.outputs.server_archive }} | |
| dist/${{ steps.package.outputs.bootstrap_jar }} | |
| dist/${{ steps.package.outputs.client_launcher_jar }} | |
| dist/${{ steps.package.outputs.supervisor_jar }} | |
| dist/release.json | |
| dist/release.sig |