mirror of
https://github.com/OliveTin/OliveTin
synced 2026-08-23 11:06:29 +00:00
272 lines
9.7 KiB
YAML
272 lines
9.7 KiB
YAML
---
|
|
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: frontend unit tests
|
|
run: make -w frontend-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: Verify macOS signing certificate chain
|
|
if: github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
|
|
env:
|
|
MACOS_SIGN_P12: ${{ secrets.MACOS_SIGN_P12 }}
|
|
MACOS_SIGN_PASSWORD: ${{ secrets.MACOS_SIGN_PASSWORD }}
|
|
run: ./var/macos/verify-macos-sign-p12.sh
|
|
|
|
- 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: |
|
|
# SignPath may name the signed zip *.zip.zip (one compression level, bad Content-Disposition).
|
|
if [[ -f signed-windows-zip/OliveTin-windows-amd64.zip.zip ]]; then
|
|
mv signed-windows-zip/OliveTin-windows-amd64.zip.zip \
|
|
signed-windows-zip/OliveTin-windows-amd64.zip
|
|
fi
|
|
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}"
|