Skip to content

Release

Release #5

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to build (e.g. v0.1.0)'
required: true
type: string
# REPLACE these per-project:
env:
# Path to the CLI crate inside joulesperbit.
# The Cargo package name is the last path segment; the build uses
# `-p ${CLI_CRATE_PATH##*/}` -> `-p joulec`. The full-pipeline Rust compiler
# lives at compiler/joulec (package `joulec`), not bootstrap (which is the
# separate `joule-bootstrap-tools` package and does not produce this binary).
CLI_CRATE_PATH: crates/joule-lang/compiler/joulec
# Self-contained nested cargo workspace that owns joulec. The joulesperbit
# monorepo root workspace is NOT buildable from a fresh checkout (some members
# path-depend on external sibling repos), so we build from this inner
# workspace, which is clean and has no external/registry dependencies.
WORKSPACE_DIR: joulesperbit/crates/joule-lang
# Name of the CLI binary that ends up in target/release/
BIN_NAME: joulec
# Public name (what the tarball is named)
RELEASE_NAME: joulec
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-apple-darwin
os: macos-14
archive: tar.gz
- target: aarch64-apple-darwin
os: macos-14
archive: tar.gz
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
archive: tar.gz
use-cross: true
- target: aarch64-unknown-linux-musl
os: ubuntu-latest
archive: tar.gz
use-cross: true
- target: x86_64-pc-windows-msvc
os: windows-latest
archive: zip
steps:
- name: Resolve tag
id: tag
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
fi
- name: Checkout public release surface
uses: actions/checkout@v4
- name: Checkout private source
uses: actions/checkout@v4
with:
repository: openIE-dev/joulesperbit
token: ${{ secrets.JOULESPERBIT_READ_TOKEN }}
path: joulesperbit
ref: ${{ steps.tag.outputs.tag }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross (Linux only)
if: matrix.use-cross
run: cargo install cross --locked
- name: Build
shell: bash
working-directory: ${{ env.WORKSPACE_DIR }}
run: |
if [ "${{ matrix.use-cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }} -p "${CLI_CRATE_PATH##*/}"
else
cargo build --release --target ${{ matrix.target }} -p "${CLI_CRATE_PATH##*/}"
fi
- name: Package
shell: bash
run: |
STAGE=$(mktemp -d)
TAG="${{ steps.tag.outputs.tag }}"
BASE="${RELEASE_NAME}-${TAG#v}-${{ matrix.target }}"
mkdir -p "$STAGE/$BASE"
if [ "${{ matrix.target }}" = "x86_64-pc-windows-msvc" ]; then
cp "${WORKSPACE_DIR}/target/${{ matrix.target }}/release/${BIN_NAME}.exe" "$STAGE/$BASE/"
else
cp "${WORKSPACE_DIR}/target/${{ matrix.target }}/release/${BIN_NAME}" "$STAGE/$BASE/"
fi
cp LICENSE README.md "$STAGE/$BASE/" 2>/dev/null || true
cd "$STAGE"
if [ "${{ matrix.archive }}" = "zip" ]; then
(cd "$BASE" && 7z a -tzip "../${BASE}.zip" .)
mv "${BASE}.zip" "${{ github.workspace }}/"
(cd "${{ github.workspace }}" && shasum -a 256 "${BASE}.zip" > "${BASE}.zip.sha256")
else
tar czf "${BASE}.tar.gz" "$BASE"
mv "${BASE}.tar.gz" "${{ github.workspace }}/"
(cd "${{ github.workspace }}" && shasum -a 256 "${BASE}.tar.gz" > "${BASE}.tar.gz.sha256")
fi
ls -la "${{ github.workspace }}"/*${BASE}*
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}-${{ matrix.target }}
path: |
${{ env.RELEASE_NAME }}-*-${{ matrix.target }}.tar.gz*
${{ env.RELEASE_NAME }}-*-${{ matrix.target }}.zip*
release:
name: Publish Release
needs: build
# Publish whatever built. With fail-fast:false the matrix legs are
# independent; if an unverified target (e.g. musl/windows) fails, the
# platforms that did build still ship. An empty dist still fails below
# via fail_on_unmatched_files, so a total build failure is not masked.
if: ${{ always() }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Collect
run: |
mkdir -p dist
find artifacts -type f \( -name '*.tar.gz' -o -name '*.zip' -o -name '*.sha256' \) -exec mv {} dist/ \;
ls -la dist/
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: dist/*
generate_release_notes: true
fail_on_unmatched_files: true