diff options
| author | Nikolay Govorov <me@govorov.online> | 2026-04-08 17:20:24 +0100 |
|---|---|---|
| committer | Nikolay Govorov <me@govorov.online> | 2026-04-08 17:31:27 +0100 |
| commit | cb311847ae2c570b0fd2afaf7cb0f8aa7ec9acd3 (patch) | |
| tree | a295284360e4acdb5d85b727d2fa4dcfb210eef9 | |
| parent | d996e025a8ea157a26dbd2b62861aeba4420bff9 (diff) | |
| download | tar tar.gz tar.bz2 tar.lz tar.xz tar.zst zip | |
Degreases GitHub actions
Diffstat
| -rw-r--r-- | .github/workflows/build.yml | 191 | +25 −166 |
| -rw-r--r-- | Taskfile.yml | 157 | +149 −8 |
2 files changed, 174 insertions, 174 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dcf9532..ddc44a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,11 +12,10 @@ on: jobs: build: - name: Build + name: Build and publish Nightly runs-on: ubuntu-latest - outputs: - channel: ${{ steps.version.outputs.channel }} - version: ${{ steps.version.outputs.version }} + permissions: + contents: write steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: @@ -29,180 +28,40 @@ jobs: - 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 + sudo apt update && sudo apt install nfpm apt-utils rclone createrepo-c sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin curl -sSL "https://github.com/bufbuild/buf/releases/download/v1.67.0/buf-$(uname -s)-$(uname -m)" -o /usr/local/bin/buf && chmod +x /usr/local/bin/buf go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install connectrpc.com/connect/cmd/protoc-gen-connect-go@latest - - - name: Check licenses - uses: fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0 - - - name: Check git history - run: task signof - - - 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: 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 + pipx install reuse - name: Build and package - 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 + run: task package GIT_REF=${{ github.ref }} GPG_KEY_ID=${{ vars.GPG_KEY_ID }} env: - GPG_KEY_ID: ${{ vars.GPG_KEY_ID }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - - name: Lint - run: task lint + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - name: Test - run: task test + - name: CI checks + run: task ci - - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - 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: write - steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - 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: packages - path: dist - - # 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' + - 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" - git tag -f nightly - git push origin --force tag nightly - - - name: Delete old nightly assets - if: needs.build.outputs.channel == 'nightly' - run: | - 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: Create GitHub Release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 - with: - 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 }} + . build/dist/build.env + task publish:release CHANNEL=$CHANNEL VERSION=$VERSION + task publish:repos \ + CHANNEL=$CHANNEL \ + S3_BUCKET=${{ vars.S3_BUCKET }} \ + S3_PUBLIC_URL=${{ vars.S3_PUBLIC_URL }} \ + S3_PROVIDER="${{ vars.S3_PROVIDER || 'Other' }}" \ + S3_REGION=${{ vars.S3_REGION }} \ + S3_ENDPOINT=${{ vars.S3_ENDPOINT }} \ + GPG_KEY_ID=${{ vars.GPG_KEY_ID }} env: 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: | - gpg --export --armor "${{ vars.GPG_KEY_ID }}" > public.gpg - rclone copyto public.gpg "s3:${{ vars.S3_BUCKET }}/public.gpg" - rclone copy pkg/dl/ "s3:${{ vars.S3_BUCKET }}/" - - - name: Create APT repository - run: | - CHANNEL=${{ needs.build.outputs.channel }} - - mkdir -p apt-repo - rclone copy "s3:${{ vars.S3_BUCKET }}/apt/" apt-repo/ - - 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 - - rclone copy rpm-repo/ "s3:${{ vars.S3_BUCKET }}/rpm/$CHANNEL/" --progress + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} + S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} diff --git a/Taskfile.yml b/Taskfile.yml index b2dbaaa..b3090e6 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -12,10 +12,18 @@ vars: DEV_DB: mirum-local-dev tasks: + ci: + desc: Run all CI checks + cmds: + - task: signof + - task: lint + - task: test + lint: desc: Run static checks deps: [proto] cmds: + - reuse lint - go vet ./... - gofmt -l . | grep . && exit 1 || true @@ -236,17 +244,150 @@ tasks: package: desc: Build deb/rpm packages for all architectures - requires: - vars: [VERSION] + vars: + VERSION: + sh: | + ref="${GIT_REF:-$(git describe --tags --exact-match 2>/dev/null || echo "")}" + if [[ "$ref" == refs/tags/v* ]]; then + echo "${ref#refs/tags/v}" + elif [[ "$ref" == v* ]]; then + echo "${ref#v}" + else + echo "$(cat VERSION)~nightly.$(git log -1 --format=%ct)" + fi + CHANNEL: + sh: | + ref="${GIT_REF:-$(git describe --tags --exact-match 2>/dev/null || echo "")}" + if [[ "$ref" == refs/tags/v* || "$ref" == v* ]]; then echo stable; else echo nightly; fi env: VERSION: "{{.VERSION}}" cmds: - - mkdir -p {{.DIST_DIR}} - - for: { var: ARCHES } - cmd: | - task build GOOS=linux GOARCH={{.ITEM}} - ARCH={{.ITEM}} nfpm package --packager deb --target {{.DIST_DIR}}/ - ARCH={{.ITEM}} nfpm package --packager rpm --target {{.DIST_DIR}}/ + - | + cleanup() { rm -rf "$GNUPGHOME" /tmp/mirum-signing.asc 2>/dev/null; } + trap cleanup EXIT + + if [ -n "${GPG_PRIVATE_KEY:-}" ]; then + export GNUPGHOME=$(mktemp -d) + chmod 700 "$GNUPGHOME" + printf '%s' "$GPG_PRIVATE_KEY" > /tmp/mirum-signing.asc + chmod 600 /tmp/mirum-signing.asc + gpg --batch --yes --passphrase "$GPG_PASSPHRASE" --import /tmp/mirum-signing.asc + export GPG_KEY_ID="{{.GPG_KEY_ID}}" + export SIGNING_PRIVATE_KEY="/tmp/mirum-signing.asc" + export NFPM_PASSPHRASE="$GPG_PASSPHRASE" + fi + + mkdir -p {{.DIST_DIR}} + for arch in {{.ARCHES}}; do + task build GOOS=linux GOARCH=$arch + ARCH=$arch nfpm package --packager deb --target {{.DIST_DIR}}/ + ARCH=$arch nfpm package --packager rpm --target {{.DIST_DIR}}/ rm {{.BUILD_DIR}}/mirumd {{.BUILD_DIR}}/mirumw + done + + printf 'VERSION={{.VERSION}}\nCHANNEL={{.CHANNEL}}\n' > {{.DIST_DIR}}/build.env + + publish:release: + desc: Create or update a GitHub Release + requires: + vars: [CHANNEL, VERSION] + cmds: + - | + if [ "{{.CHANNEL}}" = "stable" ]; then + TAG="v{{.VERSION}}" + NAME="{{.VERSION}}" + else + TAG="nightly" + NAME="nightly" + git tag -f nightly + git push origin --force tag nightly + 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 + fi + + gh release create "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm \ + --title "$NAME" \ + $( [ "{{.CHANNEL}}" = "nightly" ] && echo "--prerelease" ) \ + --notes "**Version**: {{.VERSION}}" \ + || gh release upload "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm --clobber + + publish:repos: + desc: Publish packages to APT and RPM repositories on S3 + requires: + vars: [CHANNEL, S3_BUCKET, S3_PUBLIC_URL, S3_PROVIDER, S3_REGION, S3_ENDPOINT, GPG_KEY_ID] + cmds: + - | + set -e + export GNUPGHOME=$(mktemp -d) + RCLONE_CONF=$(mktemp) + chmod 700 "$GNUPGHOME" + cleanup() { rm -rf "$GNUPGHOME" "$RCLONE_CONF"; } + trap cleanup EXIT + + cat > "$RCLONE_CONF" << EOF + [s3] + type = s3 + provider = {{.S3_PROVIDER}} + access_key_id = ${S3_ACCESS_KEY_ID} + secret_access_key = ${S3_SECRET_ACCESS_KEY} + region = {{.S3_REGION}} + endpoint = {{.S3_ENDPOINT}} + EOF + export RCLONE_CONFIG="$RCLONE_CONF" + + printf '%s' "$GPG_PRIVATE_KEY" | gpg --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --import + echo "allow-loopback-pinentry" >> "$GNUPGHOME/gpg-agent.conf" + gpgconf --kill gpg-agent + + # Upload static files + gpg --export --armor "{{.GPG_KEY_ID}}" > "$GNUPGHOME/public.gpg" + rclone copyto "$GNUPGHOME/public.gpg" "s3:{{.S3_BUCKET}}/public.gpg" + rclone copy pkg/dl/ "s3:{{.S3_BUCKET}}/" + + # APT repository + CHANNEL={{.CHANNEL}} + mkdir -p /tmp/apt-cache apt-repo + rclone copy "s3:{{.S3_BUCKET}}/apt/" apt-repo/ + + for ch in stable nightly; do + mkdir -p apt-repo/pool/$ch + for arch in {{.ARCHES}}; do + mkdir -p apt-repo/dists/$ch/main/binary-$arch + done + done + cp {{.DIST_DIR}}/*.deb apt-repo/pool/$CHANNEL/ + + cd apt-repo + apt-ftparchive generate "$(pwd)/../pkg/apt-ftparchive.conf" + apt-ftparchive \ + -o APT::FTPArchive::Release::Codename=$CHANNEL \ + -o APT::FTPArchive::Release::Components=main \ + -o APT::FTPArchive::Release::Architectures="{{.ARCHES}}" \ + release dists/$CHANNEL/ > dists/$CHANNEL/Release + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" -abs -o dists/$CHANNEL/Release.gpg dists/$CHANNEL/Release + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --clearsign -o dists/$CHANNEL/InRelease dists/$CHANNEL/Release + cd .. + rclone copy apt-repo/ "s3:{{.S3_BUCKET}}/apt/" --progress + + # RPM repository + mkdir -p rpm-repo + rclone copy "s3:{{.S3_BUCKET}}/rpm/$CHANNEL/" rpm-repo/ + + cp {{.DIST_DIR}}/*.rpm rpm-repo/ + + createrepo_c --update rpm-repo/ + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --detach-sign --armor rpm-repo/repodata/repomd.xml + + cat > rpm-repo/mirum-${CHANNEL}.repo << REPOEOF + [mirum-${CHANNEL}] + name=Mirum ${CHANNEL} + gpgkey={{.S3_PUBLIC_URL}}/public.gpg + baseurl={{.S3_PUBLIC_URL}}/rpm/${CHANNEL}/ + enabled=1 + gpgcheck=1 + REPOEOF + + rclone copy rpm-repo/ "s3:{{.S3_BUCKET}}/rpm/$CHANNEL/" --progress # yaml-language-server: $schema=https://taskfile.dev/schema.json |
