| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- ---
- name: "Build & Release pipeline"
- on:
- pull_request:
- paths:
- - '.github/workflows/build-and-release.yml'
- - '.goreleaser.yml'
- - 'Dockerfile.multiarches'
- - 'Dockerfile.singlearch'
- - 'Makefile'
- - 'frontend/**'
- - 'integration-tests/**'
- - 'proto/**'
- - 'service/**'
- - 'var/windows/**'
- workflow_dispatch:
- push:
- tags:
- - '*'
- branches:
- - main
- - next
- - beta
- paths:
- - '.github/workflows/build-and-release.yml'
- - '.goreleaser.yml'
- - 'Dockerfile.multiarches'
- - 'Dockerfile.singlearch'
- - 'Makefile'
- - 'frontend/**'
- - 'integration-tests/**'
- - 'proto/**'
- - 'service/**'
- - 'var/windows/**'
- jobs:
- build:
- runs-on: ubuntu-latest
- outputs:
- new_release_published: ${{ steps.release.outputs.new_release_published }}
- new_release_git_tag: ${{ steps.release.outputs.new_release_git_tag }}
- windows_zip_artifact_id: ${{ steps.upload-windows-zip.outputs.artifact-id }}
- windows_msi_artifact_id: ${{ steps.upload-windows-msi.outputs.artifact-id }}
- steps:
- - name: Checkout
- uses: actions/checkout@v6
- with:
- fetch-depth: 0
- - name: Set up QEMU
- id: qemu
- uses: docker/setup-qemu-action@v4
- with:
- image: tonistiigi/binfmt:latest
- platforms: arm64,arm
- - name: Setup node (npm cache)
- if: github.event_name != 'pull_request'
- uses: actions/setup-node@v6.4.0
- with:
- node-version: '22'
- cache: 'npm'
- cache-dependency-path: frontend/package-lock.json
- - name: Setup node
- if: github.event_name == 'pull_request'
- uses: actions/setup-node@v6.4.0
- with:
- node-version: '22'
- - name: Setup Go
- uses: actions/setup-go@v6
- with:
- go-version-file: 'service/go.mod'
- cache: true
- cache-dependency-path: 'service/go.mod'
- - name: Print go version
- run: go version
- - name: Login to Docker Hub
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- uses: docker/login-action@v4
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_KEY }}
- - name: Login to ghcr
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- uses: docker/login-action@v4
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.CONTAINER_TOKEN }}
- - name: get date
- run: |
- echo "DATE=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"
- - name: make webui
- run: make -w webui-dist
- - name: unit tests
- run: make -w service-unittests
- - name: build service
- run: make -w service
- - name: integration tests
- run: cd integration-tests && make -w
- - name: Archive integration tests
- uses: actions/upload-artifact@v7
- if: always()
- with:
- name: "OliveTin-integration-tests-${{ env.DATE }}-${{ github.sha }}"
- path: |
- integration-tests
- !integration-tests/node_modules
- - name: Install wixl and msitools
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- run: sudo apt-get update && sudo apt-get install -y wixl msitools
- - name: Install goreleaser
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- uses: goreleaser/goreleaser-action@v7
- with:
- install-only: true
- - name: Set up Docker Buildx
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- uses: docker/setup-buildx-action@v4
- - name: release
- id: release
- if: github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
- uses: cycjimmy/semantic-release-action@v5
- with:
- extra_plugins: |
- @semantic-release/commit-analyzer
- @semantic-release/exec
- @semantic-release/git
- env:
- GITHUB_TOKEN: ${{ secrets.CONTAINER_TOKEN }}
- GH_TOKEN: ${{ secrets.CONTAINER_TOKEN }}
- MACOS_SIGN_P12: ${{ secrets.MACOS_SIGN_P12 }}
- MACOS_SIGN_PASSWORD: ${{ secrets.MACOS_SIGN_PASSWORD }}
- MACOS_NOTARY_KEY: ${{ secrets.MACOS_NOTARY_KEY }}
- MACOS_NOTARY_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
- MACOS_NOTARY_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
- - name: Upload unsigned Windows zip for SignPath
- id: upload-windows-zip
- if: steps.release.outputs.new_release_published == 'true'
- uses: actions/upload-artifact@v7
- with:
- # Upload as-is so SignPath receives OliveTin-windows-amd64.zip, not a wrapper zip.
- # With archive: false, the artifact name is the filename (`name` is ignored).
- path: dist/OliveTin-windows-amd64.zip
- archive: false
- if-no-files-found: error
- - name: Upload unsigned Windows MSI for SignPath
- id: upload-windows-msi
- if: steps.release.outputs.new_release_published == 'true'
- uses: actions/upload-artifact@v7
- with:
- path: dist/OliveTin-windows-amd64.msi
- archive: false
- if-no-files-found: error
- - name: Archive binaries
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
- uses: actions/upload-artifact@v7
- with:
- name: "OliveTin-snapshot-${{ env.DATE }}-${{ github.sha }}"
- path: dist/OliveTin*.*
- sign-windows:
- name: Sign Windows artifacts (SignPath)
- needs: build
- if: needs.build.outputs.new_release_published == 'true'
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: write
- steps:
- - name: Checkout
- uses: actions/checkout@v6
- with:
- persist-credentials: false
- - name: Require SignPath configuration
- env:
- SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
- SIGNPATH_ORGANIZATION_ID: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
- SIGNPATH_PROJECT_SLUG: ${{ vars.SIGNPATH_PROJECT_SLUG }}
- SIGNPATH_SIGNING_POLICY_SLUG: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
- run: |
- missing=0
- for name in SIGNPATH_API_TOKEN SIGNPATH_ORGANIZATION_ID SIGNPATH_PROJECT_SLUG SIGNPATH_SIGNING_POLICY_SLUG; do
- if [[ -z "${!name}" ]]; then
- echo "Missing required SignPath setting: ${name}" >&2
- missing=1
- fi
- done
- if [[ "${missing}" -ne 0 ]]; then
- echo "SignPath secrets/vars are required to upload signed Windows assets. Configure them (see docs/modules/dev/pages/signing.adoc)." >&2
- exit 1
- fi
- - name: Sign Windows zip
- uses: signpath/github-action-submit-signing-request@v2
- with:
- api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
- organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
- project-slug: ${{ vars.SIGNPATH_PROJECT_SLUG }}
- signing-policy-slug: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
- artifact-configuration-slug: windows-zip
- github-artifact-id: ${{ needs.build.outputs.windows_zip_artifact_id }}
- wait-for-completion: true
- # Preserve the signed .zip/.msi files; default decompress would unpack the zip.
- skip-decompress: true
- output-artifact-directory: signed-windows-zip
- - name: Sign Windows MSI
- uses: signpath/github-action-submit-signing-request@v2
- with:
- api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
- organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
- project-slug: ${{ vars.SIGNPATH_PROJECT_SLUG }}
- signing-policy-slug: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
- artifact-configuration-slug: windows-msi
- github-artifact-id: ${{ needs.build.outputs.windows_msi_artifact_id }}
- wait-for-completion: true
- skip-decompress: true
- output-artifact-directory: signed-windows-msi
- - name: Upload signed Windows assets
- env:
- GH_TOKEN: ${{ secrets.CONTAINER_TOKEN }}
- GITHUB_TOKEN: ${{ secrets.CONTAINER_TOKEN }}
- run: |
- zip_path="$(find signed-windows-zip -type f -name 'OliveTin-windows-amd64.zip' | head -n 1)"
- msi_path="$(find signed-windows-msi -type f -name 'OliveTin-windows-amd64.msi' | head -n 1)"
- if [[ -z "${zip_path}" || -z "${msi_path}" ]]; then
- echo "Signed Windows artifacts not found after SignPath:" >&2
- find signed-windows-zip signed-windows-msi -type f >&2 || true
- exit 1
- fi
- ./var/windows/signpath-publish-signed.sh \
- "${{ needs.build.outputs.new_release_git_tag }}" \
- "${zip_path}" \
- "${msi_path}"
|