# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json name: Release on: push: tags: - "v*" workflow_dispatch: inputs: tag: description: "Release tag" required: true type: string env: REGISTRY: ghcr.io CARGO_TERM_COLOR: always SQLX_OFFLINE: true jobs: create-release: name: Create Release runs-on: ubuntu-latest outputs: release_id: ${{ steps.create_release.outputs.id }} upload_url: ${{ steps.create_release.outputs.upload_url }} tag: ${{ steps.tag.outputs.tag }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Get tag name id: tag run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT else echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT fi - name: Generate changelog id: changelog run: | if [ -f "CHANGELOG.md" ]; then # Extract changelog for this version awk '/^## \[${{ steps.tag.outputs.tag }}\]/{flag=1; next} /^## \[/{flag=0} flag' CHANGELOG.md > release_notes.md else echo "Release ${{ steps.tag.outputs.tag }}" > release_notes.md fi - name: Create Release id: create_release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ steps.tag.outputs.tag }} release_name: Release ${{ steps.tag.outputs.tag }} body_path: release_notes.md draft: false prerelease: ${{ contains(steps.tag.outputs.tag, '-') }} build-all: name: Build All Artifacts runs-on: ubuntu-latest needs: create-release outputs: rust-artifacts: ${{ steps.upload-rust.outputs.artifact-id }} node-artifacts: ${{ steps.upload-node.outputs.artifact-id }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup environment uses: ./.github/actions/setup with: setup-rust: "true" setup-node: "true" cache-key-suffix: "release-${{ needs.create-release.outputs.tag }}" - name: Install cross-compilation tools run: | cargo install cross rustup target add aarch64-unknown-linux-gnu - name: Build Node.js artifacts run: | pnpm build cd apps/amethyst && pnpm build - name: Build Rust services (x86_64) run: | cd services cargo build --release --all-features - name: Build Rust services (aarch64) run: | cd services cross build --release --all-features --target aarch64-unknown-linux-gnu - name: Build Rust apps (x86_64) run: | cd apps/aqua cargo build --release --all-features - name: Build Rust apps (aarch64) run: | cd apps/aqua cross build --release --all-features --target aarch64-unknown-linux-gnu - name: Create Amethyst build archive run: | cd apps/amethyst tar -czf amethyst-${{ needs.create-release.outputs.tag }}.tar.gz build/ - name: Upload Rust build artifacts id: upload-rust uses: actions/upload-artifact@v4 with: name: rust-release-builds path: | target/release/ target/aarch64-unknown-linux-gnu/release/ apps/aqua/target/release/ apps/aqua/target/aarch64-unknown-linux-gnu/release/ retention-days: 7 - name: Upload Node build artifacts id: upload-node uses: actions/upload-artifact@v4 with: name: node-release-builds path: | packages/*/dist/ apps/amethyst/build/ apps/amethyst/amethyst-${{ needs.create-release.outputs.tag }}.tar.gz retention-days: 7 - name: Upload Amethyst build to release uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ needs.create-release.outputs.upload_url }} asset_path: ./apps/amethyst/amethyst-${{ needs.create-release.outputs.tag }}.tar.gz asset_name: amethyst-${{ needs.create-release.outputs.tag }}.tar.gz asset_content_type: application/gzip release-services: name: Release Services runs-on: ubuntu-latest needs: [create-release, build-all] permissions: contents: read packages: write strategy: matrix: service: - name: aqua dockerfile: apps/aqua/Dockerfile context: . - name: cadet dockerfile: services/cadet/Dockerfile context: . - name: rocketman dockerfile: services/rocketman/Dockerfile context: . - name: satellite dockerfile: services/satellite/Dockerfile context: . steps: - name: Checkout repository uses: actions/checkout@v4 - name: Check if service has Dockerfile id: check run: | if [ -f "${{ matrix.service.dockerfile }}" ]; then echo "has_dockerfile=true" >> $GITHUB_OUTPUT echo "Service ${{ matrix.service.name }} has Dockerfile" else echo "has_dockerfile=false" >> $GITHUB_OUTPUT echo "Service ${{ matrix.service.name }} does not have Dockerfile, skipping" fi - name: Setup environment if: steps.check.outputs.has_dockerfile == 'true' uses: ./.github/actions/setup with: setup-node: "true" lexicons-only-rust: "true" - name: Download build artifacts if: steps.check.outputs.has_dockerfile == 'true' uses: actions/download-artifact@v4 with: name: rust-release-builds path: . - name: Log in to Container Registry if: steps.check.outputs.has_dockerfile == 'true' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata if: steps.check.outputs.has_dockerfile == 'true' id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.service.name }} tags: | type=raw,value=latest type=raw,value=${{ needs.create-release.outputs.tag }} - name: Set up Docker Buildx if: steps.check.outputs.has_dockerfile == 'true' uses: docker/setup-buildx-action@v3 - name: Build and push Docker image if: steps.check.outputs.has_dockerfile == 'true' uses: docker/build-push-action@v5 with: context: ${{ matrix.service.context }} file: ${{ matrix.service.dockerfile }} push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} platforms: linux/amd64,linux/arm64 cache-from: type=gha,scope=${{ matrix.service.name }} cache-to: type=gha,mode=max,scope=${{ matrix.service.name }} build-args: | BUILDKIT_INLINE_CACHE=1