Skip to content

Build and Publish

Build and Publish #10

name: Build and Publish
on:
workflow_run:
workflows: ["Build and Test"]
branches: [main]
types:
- completed
workflow_dispatch:
inputs:
skip_crates_io:
description: 'Skip publishing to crates.io'
type: boolean
default: false
skip_docs:
description: 'Skip publishing documentation'
type: boolean
default: false
force_version_tags:
description: 'Force version tags regardless of version change'
type: boolean
default: false
permissions:
contents: write # Needed for creating releases
packages: write # Needed for Docker publishing
concurrency:
group: ${{ github.workflow }}-${{ github.run_id }}
cancel-in-progress: false
jobs:
prepare:
name: Prepare
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-22.04
outputs:
version: ${{ steps.version_info.outputs.version }}
version_changed: ${{ steps.version_info.outputs.version_changed }}
is_rc: ${{ steps.version_info.outputs.is_rc }}
sha: ${{ steps.get_sha.outputs.sha }}
previous_version: ${{ steps.version_info.outputs.previous_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Load common configuration
id: config
uses: ./.github/actions/load-config
- name: Get SHA
id: get_sha
run: |
SHORT_SHA=${GITHUB_SHA::7}
echo "sha=$SHORT_SHA" >> $GITHUB_OUTPUT
- name: Get version information
id: version_info
uses: ./.github/actions/get-version-info
with:
force_version_tags: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_version_tags == 'true' }}
- name: Log version information
run: |
if [[ "${{ steps.version_info.outputs.version_changed }}" == "true" ]]; then
echo "## Building with version tags" >> $GITHUB_STEP_SUMMARY
echo "Version has changed or force_version_tags is enabled. Will publish all artifacts with version tags." >> $GITHUB_STEP_SUMMARY
else
echo "## Building with SHA tags only" >> $GITHUB_STEP_SUMMARY
echo "The version hasn't changed since the last release. Will only publish Docker images with SHA tags." >> $GITHUB_STEP_SUMMARY
fi
build-binaries:
name: Build Binaries - ${{ matrix.target }}
needs: prepare
if: needs.prepare.outputs.version_changed == 'true' && github.ref == 'refs/heads/main'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact-name: starknet-devnet-x86_64-unknown-linux-gnu
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
artifact-name: starknet-devnet-aarch64-unknown-linux-gnu
- os: ubuntu-22.04
target: x86_64-unknown-linux-musl
artifact-name: starknet-devnet-x86_64-unknown-linux-musl
- os: macos-14
target: x86_64-apple-darwin
artifact-name: starknet-devnet-x86_64-apple-darwin
- os: macos-14
target: aarch64-apple-darwin
artifact-name: starknet-devnet-aarch64-apple-darwin
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Load common configuration
id: config
uses: ./.github/actions/load-config
- name: Set up Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.config.outputs.rust_stable_version }}
target: ${{ matrix.target }}
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: binary-${{ matrix.target }}
cache-on-failure: true
- name: Install cross-compilation dependencies for Linux targets
if: runner.os == 'Linux' && contains(matrix.target, '-unknown-linux-')
run: |
if [[ "${{ matrix.target }}" == *"-musl" ]]; then
sudo apt-get update
sudo apt-get install -y musl-tools
fi
if [[ "${{ matrix.target }}" == "aarch64-"* ]]; then
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
fi
- name: Setup for AArch64 Linux target
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config.toml
echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config.toml
- name: Add target and compile binary
run: |
rustup target add ${{ matrix.target }}
cargo build --release --target=${{ matrix.target }} --bin starknet-devnet
- name: Archive binary
run: tar -czvf ${{ matrix.artifact-name }}.tar.gz --directory target/${{ matrix.target }}/release starknet-devnet
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: ${{ matrix.artifact-name }}.tar.gz
retention-days: 14
build-docker:
name: Build Docker Images
needs: prepare
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Load common configuration
id: config
uses: ./.github/actions/load-config
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64,amd64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Prepare SHA tags
id: sha_tags
run: |
DOCKER_REGISTRY="${{ steps.config.outputs.docker_registry }}"
DOCKER_NAMESPACE="${{ steps.config.outputs.docker_namespace }}"
IMAGE_NAME="${{ steps.config.outputs.image_name }}"
SHA="${{ needs.prepare.outputs.sha }}"
SHA_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:sha-$SHA"
SHA_SEED0_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:sha-$SHA-seed0"
echo "sha_tag=$SHA_TAG" >> $GITHUB_OUTPUT
echo "sha_seed0_tag=$SHA_SEED0_TAG" >> $GITHUB_OUTPUT
- name: Prepare version tags
id: version_tags
if: ${{ needs.prepare.outputs.version_changed == 'true' }}
run: |
DOCKER_REGISTRY="${{ steps.config.outputs.docker_registry }}"
DOCKER_NAMESPACE="${{ steps.config.outputs.docker_namespace }}"
IMAGE_NAME="${{ steps.config.outputs.image_name }}"
VERSION="${{ needs.prepare.outputs.version }}"
VERSION_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:$VERSION"
VERSION_SEED0_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:$VERSION-seed0"
echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
echo "version_seed0_tag=$VERSION_SEED0_TAG" >> $GITHUB_OUTPUT
- name: Prepare latest tags
id: latest_tags
if: ${{ needs.prepare.outputs.version_changed == 'true' && needs.prepare.outputs.is_rc == 'false' }}
run: |
DOCKER_REGISTRY="${{ steps.config.outputs.docker_registry }}"
DOCKER_NAMESPACE="${{ steps.config.outputs.docker_namespace }}"
IMAGE_NAME="${{ steps.config.outputs.image_name }}"
LATEST_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:latest"
LATEST_SEED0_TAG="$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$IMAGE_NAME:latest-seed0"
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "latest_seed0_tag=$LATEST_SEED0_TAG" >> $GITHUB_OUTPUT
- name: Combine tags for standard image
id: combined_tags
run: |
TAGS=("${{ steps.sha_tags.outputs.sha_tag }}")
if [[ -n "${{ steps.version_tags.outputs.version_tag }}" ]]; then
TAGS+=("${{ steps.version_tags.outputs.version_tag }}")
fi
if [[ -n "${{ steps.latest_tags.outputs.latest_tag }}" ]]; then
TAGS+=("${{ steps.latest_tags.outputs.latest_tag }}")
fi
echo "tags=$(IFS=,; echo "${TAGS[*]}")" >> $GITHUB_OUTPUT
- name: Combine tags for seed0 image
id: combined_seed0_tags
run: |
SEED0_TAGS=("${{ steps.sha_tags.outputs.sha_seed0_tag }}")
if [[ -n "${{ steps.version_tags.outputs.version_seed0_tag }}" ]]; then
SEED0_TAGS+=("${{ steps.version_tags.outputs.version_seed0_tag }}")
fi
if [[ -n "${{ steps.latest_tags.outputs.latest_seed0_tag }}" ]]; then
SEED0_TAGS+=("${{ steps.latest_tags.outputs.latest_seed0_tag }}")
fi
echo "tags=$(IFS=,; echo "${SEED0_TAGS[*]}")" >> $GITHUB_OUTPUT
- name: Build and publish standard Docker image
id: build_standard
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.combined_tags.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and publish seed0 Docker image
id: build_seed0
uses: docker/build-push-action@v5
with:
context: .
file: ./seed0.Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.combined_seed0_tags.outputs.tags }}
build-args: |
BASE_IMAGE=${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:sha-${{ needs.prepare.outputs.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Summarize published images
run: |
echo "# Docker images published" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Standard image tags:" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ steps.sha_tags.outputs.sha_tag }}\`" >> $GITHUB_STEP_SUMMARY
if [[ -n "${{ steps.version_tags.outputs.version_tag }}" ]]; then
echo "- \`${{ steps.version_tags.outputs.version_tag }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [[ -n "${{ steps.latest_tags.outputs.latest_tag }}" ]]; then
echo "- \`${{ steps.latest_tags.outputs.latest_tag }}\`" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Seed0 image tags:" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ steps.sha_tags.outputs.sha_seed0_tag }}\`" >> $GITHUB_STEP_SUMMARY
if [[ -n "${{ steps.version_tags.outputs.version_seed0_tag }}" ]]; then
echo "- \`${{ steps.version_tags.outputs.version_seed0_tag }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [[ -n "${{ steps.latest_tags.outputs.latest_seed0_tag }}" ]]; then
echo "- \`${{ steps.latest_tags.outputs.latest_seed0_tag }}\`" >> $GITHUB_STEP_SUMMARY
fi
publish:
name: Publish to crates.io and GitHub releases
needs: [prepare, build-binaries, build-docker]
if: needs.prepare.outputs.version_changed == 'true' && github.ref == 'refs/heads/main'
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Load common configuration
id: config
uses: ./.github/actions/load-config
- name: Set up Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.config.outputs.rust_stable_version }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Publish to crates.io
if: ${{ !inputs.skip_crates_io }}
run: ./scripts/publish_cratesio_new_versions.sh
env:
CRATES_IO_API_KEY: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Publish docs
if: ${{ !inputs.skip_docs }}
env:
GIT_USER: ${{ github.actor }}
GIT_PASS: ${{ secrets.GITHUB_TOKEN }}
run: |
cd website
npm ci
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "GitHub Actions"
npm run deploy
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
name: v${{ needs.prepare.outputs.version }}
tag_name: v${{ needs.prepare.outputs.version }}
draft: false
prerelease: ${{ needs.prepare.outputs.is_rc }}
generate_release_notes: true
files: |
artifacts/starknet-devnet-x86_64-unknown-linux-gnu/starknet-devnet-x86_64-unknown-linux-gnu.tar.gz
artifacts/starknet-devnet-aarch64-unknown-linux-gnu/starknet-devnet-aarch64-unknown-linux-gnu.tar.gz
artifacts/starknet-devnet-x86_64-unknown-linux-musl/starknet-devnet-x86_64-unknown-linux-musl.tar.gz
artifacts/starknet-devnet-x86_64-apple-darwin/starknet-devnet-x86_64-apple-darwin.tar.gz
artifacts/starknet-devnet-aarch64-apple-darwin/starknet-devnet-aarch64-apple-darwin.tar.gz
body: |
# Starknet Devnet v${{ needs.prepare.outputs.version }}
## Installation
### Binary
Download the appropriate binary for your platform from the assets below.
### Docker
```bash
# Pull by version
docker pull ${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:${{ needs.prepare.outputs.version }}
docker pull ${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:${{ needs.prepare.outputs.version }}-seed0
# Pull by SHA
docker pull ${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:sha-${{ needs.prepare.outputs.sha }}
docker pull ${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:sha-${{ needs.prepare.outputs.sha }}-seed0
${{ needs.prepare.outputs.is_rc != 'true' && '# Pull latest versions' }}
${{ needs.prepare.outputs.is_rc != 'true' && 'docker pull '}}${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:latest
${{ needs.prepare.outputs.is_rc != 'true' && 'docker pull '}}${{ steps.config.outputs.docker_registry }}/${{ steps.config.outputs.docker_namespace }}/${{ steps.config.outputs.image_name }}:latest-seed0
```
${{ needs.prepare.outputs.is_rc == 'true' && '### Note\nLatest tags are not available for release candidates.' || '' }}
### Cargo
```bash
cargo install starknet-devnet
```
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}