name: release on: push: tags: - "v*" workflow_dispatch: permissions: contents: write jobs: build-web: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: "9" - uses: actions/setup-node@v6 with: node-version: "24" - name: Install dependencies run: pnpm -C apps install --frozen-lockfile - name: Build web (standalone) env: KANDEV_VERSION: ${{ github.ref_name }} run: pnpm -C apps --filter @kandev/web build - name: Package web bundle run: bash scripts/release/package-web.sh - uses: actions/upload-artifact@v4 with: name: web-bundle path: dist/web include-hidden-files: true build-bundles: needs: build-web strategy: matrix: include: - os: ubuntu-latest platform: linux-x64 goos: linux goarch: amd64 - os: ubuntu-latest platform: linux-arm64 goos: linux goarch: arm64 cc: aarch64-linux-gnu-gcc - os: macos-14 platform: macos-x64 goos: darwin goarch: amd64 - os: macos-14 platform: macos-arm64 goos: darwin goarch: arm64 - os: ubuntu-latest platform: windows-x64 goos: windows goarch: amd64 cc: x86_64-w64-mingw32-gcc runs-on: ${{ matrix.os }} env: CGO_ENABLED: 1 GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v6 with: go-version-file: apps/backend/go.mod cache-dependency-path: apps/backend/go.sum - uses: actions/download-artifact@v4 with: name: web-bundle path: dist/web - name: Install cross-compilation tools if: matrix.cc run: | sudo apt-get update sudo apt-get install -y ${{ matrix.cc == 'aarch64-linux-gnu-gcc' && 'gcc-aarch64-linux-gnu' || 'gcc-mingw-w64-x86-64' }} - name: Build backend binaries env: CC: ${{ matrix.cc || '' }} run: | cd apps/backend mkdir -p bin EXT=${{ matrix.goos == 'windows' && '.exe' || '' }} go build -o bin/kandev${EXT} ./cmd/kandev go build -o bin/agentctl${EXT} ./cmd/agentctl - name: Package bundle run: | rm -rf dist/kandev mkdir -p dist/kandev/bin EXT=${{ matrix.goos == 'windows' && '.exe' || '' }} cp apps/backend/bin/kandev${EXT} dist/kandev/bin/ cp apps/backend/bin/agentctl${EXT} dist/kandev/bin/ mkdir -p dist/kandev/web cp -R dist/web/. dist/kandev/web/ cd dist tar -czf "kandev-${{ matrix.platform }}.tar.gz" kandev shasum -a 256 "kandev-${{ matrix.platform }}.tar.gz" > "kandev-${{ matrix.platform }}.tar.gz.sha256" - name: Upload bundle artifacts uses: actions/upload-artifact@v4 with: name: bundle-${{ matrix.platform }} path: | dist/kandev-${{ matrix.platform }}.tar.gz dist/kandev-${{ matrix.platform }}.tar.gz.sha256 publish-release: needs: build-bundles runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Generate release notes uses: orhun/git-cliff-action@v4 with: config: cliff.toml args: --latest --strip header env: OUTPUT: RELEASE_NOTES.md - name: Download bundle artifacts uses: actions/download-artifact@v4 with: pattern: bundle-* path: dist/release-assets merge-multiple: true - name: Verify release assets run: | set -euo pipefail required_platforms=(linux-x64 linux-arm64 macos-x64 macos-arm64 windows-x64) for platform in "${required_platforms[@]}"; do archive="dist/release-assets/kandev-${platform}.tar.gz" checksum="${archive}.sha256" if [ ! -f "$archive" ]; then echo "Missing required archive: $archive" >&2 exit 1 fi if [ ! -f "$checksum" ]; then echo "Missing required checksum: $checksum" >&2 exit 1 fi done ls -lh dist/release-assets - name: Publish release assets uses: softprops/action-gh-release@v2 with: body_path: RELEASE_NOTES.md files: | dist/release-assets/kandev-*.tar.gz dist/release-assets/kandev-*.tar.gz.sha256