aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat
-rw-r--r--.github/workflows/build.yml191+25 −166
-rw-r--r--Taskfile.yml157+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