aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '.github/workflows/build.yml')
-rw-r--r--.github/workflows/build.yml306+158 −148
1 files changed, 158 insertions, 148 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7e1bd0e..8dc21c0 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,10 +1,6 @@
-# SPDX-FileCopyrightText: 2026 Nikolay Govorov
+# Copyright (c) 2026 Nikolay Govorov
# SPDX-License-Identifier: AGPL-3.0-or-later
-# NOTE: Don't extend it; keep the logic in the Taskfile.
-# We're using GitHub Actions as a temporary solution
-# until Mirum can handle its own maintenance.
-
name: Build
on:
@@ -16,178 +12,192 @@ on:
jobs:
build:
- name: Build and publish Nightly
+ name: Build
runs-on: ubuntu-latest
- concurrency:
- group: >-
- package-publish-mirum-${{ github.ref == 'refs/heads/main' && 'nightly'
- || startsWith(github.ref, 'refs/tags/v') && 'stable' || github.ref }}
- cancel-in-progress: false
- permissions:
- contents: write
+ outputs:
+ channel: ${{ steps.version.outputs.channel }}
+ version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- with:
- fetch-depth: 0
- - uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3
+ - name: Check licenses
+ uses: fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0
+
+ - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
- version: 2026.7.5
- experimental: true
- install: false
+ go-version-file: go.mod
- - name: Install dependencies
- run: mise bootstrap --locked --yes --update
+ - name: Install tools
+ run: |
+ echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
+ sudo apt update && sudo apt install nfpm protobuf-compiler
+ sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
+ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+
+ - name: Import GPG key
+ uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
+ with:
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+
+ - name: Check formatting
+ run: test -z "$(gofmt -l .)"
+
+ - name: Determine version
+ id: version
+ run: |
+ if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
+ echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
+ echo "channel=stable" >> "$GITHUB_OUTPUT"
+ else
+ echo "version=$(cat VERSION)~nightly.$(git log -1 --format=%ct)" >> "$GITHUB_OUTPUT"
+ echo "channel=nightly" >> "$GITHUB_OUTPUT"
+ fi
- name: Build and package
- run: task package GIT_REF=${{ github.ref }} GPG_KEY_ID=${{ vars.GPG_KEY_ID }}
+ run: |
+ printf '%s' "$GPG_PRIVATE_KEY" > /tmp/private.asc
+ chmod 600 /tmp/private.asc
+ export SIGNING_PRIVATE_KEY="/tmp/private.asc"
+ task package VERSION=${{ steps.version.outputs.version }}
+ rm -f /tmp/private.asc
env:
+ GPG_KEY_ID: ${{ vars.GPG_KEY_ID }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
- GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- APK_PRIVATE_KEY: ${{ secrets.APK_PRIVATE_KEY }}
- PACKAGE_KEY_VERSION: ${{ vars.PACKAGE_KEY_VERSION }}
+ NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Vet
+ run: go vet ./...
- - name: Lint
- run: task lint
-
- - name: Tests
- run: task test
-
- - name: Upload container binaries
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
+ - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
- name: container-binaries
- path: |
- build/mirum-server-linux-amd64
- build/mirum-server-linux-arm64
- build/mirum-worker-linux-amd64
- build/mirum-worker-linux-arm64
- if-no-files-found: error
-
- - name: Publish
- if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
- run: |
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- . build/dist/build.env
- task publish:release CHANNEL=$CHANNEL VERSION=$VERSION
- mise run publish -- \
- --service mirum \
- --channel "$CHANNEL" \
- --input build/dist \
- deb rpm apk
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
- GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- GPG_KEY_ID: ${{ vars.GPG_KEY_ID }}
- APK_PRIVATE_KEY: ${{ secrets.APK_PRIVATE_KEY }}
- PACKAGE_KEY_VERSION: ${{ vars.PACKAGE_KEY_VERSION }}
- S3_BUCKET: ${{ vars.S3_BUCKET }}
- S3_ENDPOINT: ${{ vars.S3_ENDPOINT }}
- S3_PUBLIC_URL: ${{ vars.S3_PUBLIC_URL }}
- S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
- S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
-
- oci:
- name: OCI artifacts
- needs: [build]
+ name: packages
+ path: build/dist/*
+
+ publish:
+ name: Publish
runs-on: ubuntu-latest
+ needs: [build]
+ if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
permissions:
- contents: read
- packages: write
+ contents: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
-
- - uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3
- with:
- version: 2026.7.5
- experimental: true
- install: false
+ - name: Install tools
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y apt-utils rclone createrepo-c
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
- name: container-binaries
- path: .container
-
- - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
+ name: packages
+ path: dist
- - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
+ # Configure GPG keys
+ - name: Import GPG key
+ uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
+ with:
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ - name: Update nightly tag
+ if: needs.build.outputs.channel == 'nightly'
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git tag -f nightly
+ git push origin --force tag nightly
- - name: Determine artifact version
- id: artifact
- shell: bash
+ - name: Delete old nightly assets
+ if: needs.build.outputs.channel == 'nightly'
run: |
- base_version=$(cat VERSION)
- if [[ "$GITHUB_REF" == refs/heads/main ]]; then
- version="$base_version-nightly.$(git log -1 --format=%ct)"
- elif [[ "$GITHUB_REF" == refs/tags/v* ]]; then
- version="${GITHUB_REF_NAME#v}"
- if [[ "$version" != "$base_version" ]]; then
- echo "Tag version $version does not match VERSION $base_version" >&2
- exit 1
- fi
- else
- version="$base_version-pr.$GITHUB_RUN_NUMBER"
- fi
- echo "version=$version" >> "$GITHUB_OUTPUT"
+ for asset in $(gh release view nightly --json assets --jq '.assets[].name' 2>/dev/null || true); do
+ gh release delete-asset nightly "$asset" --yes
+ done
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Log in to GHCR
- if: github.event_name != 'pull_request'
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Log Helm in to GHCR
- if: github.event_name != 'pull_request'
+ name: ${{ needs.build.outputs.channel == 'stable' && needs.build.outputs.version || 'nightly' }}
+ tag_name: ${{ needs.build.outputs.channel == 'stable' && format('v{0}', needs.build.outputs.version) || 'nightly' }}
+ prerelease: ${{ needs.build.outputs.channel == 'nightly' }}
+ files: dist/*
+ body: |
+ **Build**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
env:
- GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ # Update APT/RPM repos on S3
+ - name: Configure rclone
+ run: |
+ mkdir -p ~/.config/rclone
+ cat > ~/.config/rclone/rclone.conf << EOF
+ [s3]
+ type = s3
+ provider = ${{ vars.S3_PROVIDER || 'Other' }}
+ access_key_id = ${{ secrets.S3_ACCESS_KEY_ID }}
+ secret_access_key = ${{ secrets.S3_SECRET_ACCESS_KEY }}
+ region = ${{ vars.S3_REGION }}
+ endpoint = ${{ vars.S3_ENDPOINT }}
+ EOF
+
+ - name: Upload static files
run: |
- printf '%s' "$GHCR_TOKEN" | mise x helm@4.1.1 -- \
- helm registry login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
+ gpg --export --armor "${{ vars.GPG_KEY_ID }}" > public.gpg
+ rclone copyto public.gpg "s3:${{ vars.S3_BUCKET }}/public.gpg"
+ rclone copyto pkg/index.html "s3:${{ vars.S3_BUCKET }}/index.html"
+ rclone copyto pkg/404.html "s3:${{ vars.S3_BUCKET }}/404.html"
- - name: Build and publish OCI artifacts
- shell: bash
+ - name: Create APT repository
run: |
- version="${{ steps.artifact.outputs.version }}"
- image_output=()
- chart_output=()
+ CHANNEL=${{ needs.build.outputs.channel }}
- if [[ "${{ github.event_name }}" != pull_request ]]; then
- image_output+=(--push)
- chart_output+=(--push "oci://ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/charts")
- fi
+ mkdir -p apt-repo
+ rclone copy "s3:${{ vars.S3_BUCKET }}/apt/" apt-repo/
- for service in server worker; do
- image="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/mirum-$service"
- tags=(
- --tag "$image:sha-$GITHUB_SHA"
- --tag "$image:$version"
- )
- labels=(
- --label "org.opencontainers.image.revision=$GITHUB_SHA"
- --label "org.opencontainers.image.source=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
- --label "org.opencontainers.image.version=$version"
- )
-
- if [[ "$GITHUB_REF" == refs/heads/main ]]; then
- tags+=(--tag "$image:nightly")
- elif [[ "$GITHUB_REF" == refs/tags/v* ]]; then
- tags+=(--tag "$image:latest")
- fi
-
- mise run container -- \
- --context . \
- --file "cmd/mirum-$service/Dockerfile" \
- --platform linux/amd64,linux/arm64 \
- --cache-scope "mirum-$service" \
- "${tags[@]}" "${labels[@]}" "${image_output[@]}"
+ mkdir -p /tmp/apt-cache
+ for ch in stable nightly; do
+ mkdir -p apt-repo/pool/$ch
+ for arch in amd64 arm64 riscv64 ppc64le; do
+ mkdir -p apt-repo/dists/$ch/main/binary-$arch
+ done
done
+ cp dist/*.deb apt-repo/pool/$CHANNEL/
+
+ cd apt-repo
+ apt-ftparchive generate "${{ github.workspace }}/pkg/apt-ftparchive.conf"
+ apt-ftparchive \
+ -o APT::FTPArchive::Release::Codename=$CHANNEL \
+ -o APT::FTPArchive::Release::Components=main \
+ -o APT::FTPArchive::Release::Architectures="amd64 arm64 riscv64 ppc64le" \
+ release dists/$CHANNEL/ > dists/$CHANNEL/Release
+ gpg --default-key="${{ vars.GPG_KEY_ID }}" --batch --yes -abs -o dists/$CHANNEL/Release.gpg dists/$CHANNEL/Release
+ gpg --default-key="${{ vars.GPG_KEY_ID }}" --batch --yes --clearsign -o dists/$CHANNEL/InRelease dists/$CHANNEL/Release
+ cd ..
+
+ rclone copy apt-repo/ "s3:${{ vars.S3_BUCKET }}/apt/" --progress
+
+ - name: Create RPM repository
+ run: |
+ CHANNEL=${{ needs.build.outputs.channel }}
+
+ mkdir -p rpm-repo
+ rclone copy "s3:${{ vars.S3_BUCKET }}/rpm/$CHANNEL/" rpm-repo/
+
+ cp dist/*.rpm rpm-repo/
+
+ createrepo_c --update rpm-repo/
+ gpg --default-key="${{ vars.GPG_KEY_ID }}" --batch --yes --detach-sign --armor rpm-repo/repodata/repomd.xml
+
+ cat > rpm-repo/mirum-${CHANNEL}.repo << EOF
+ [mirum-${CHANNEL}]
+ name=Mirum ${CHANNEL}
+ gpgkey=${{ vars.S3_PUBLIC_URL }}/public.gpg
+ baseurl=${{ vars.S3_PUBLIC_URL }}/rpm/${CHANNEL}/
+ enabled=1
+ gpgcheck=1
+ EOF
- mise run chart -- \
- --chart charts/mirum \
- --version "$version" \
- --app-version "$version" \
- "${chart_output[@]}"
+ rclone copy rpm-repo/ "s3:${{ vars.S3_BUCKET }}/rpm/$CHANNEL/" --progress