ci: pull release notes from CHANGELOG.md instead of hardcoded body #41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD — OmniBioAI Studio | |
| on: | |
| push: | |
| branches: [main, dev, "feature/**"] | |
| tags: ["v*.*.*"] | |
| pull_request: | |
| branches: [main, dev] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ── 1. Lint & Validate ────────────────────────────────── | |
| lint: | |
| name: Lint & Validate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - run: npm install | |
| - name: Validate JSON configs | |
| run: | | |
| node -e "JSON.parse(require('fs').readFileSync('package.json'))" \ | |
| && echo "✅ package.json valid" | |
| node -e "JSON.parse(require('fs').readFileSync('electron-builder.json'))" \ | |
| && echo "✅ electron-builder.json valid" | |
| - name: Validate docker-compose-release.yml | |
| env: | |
| WORKSPACE_HOST: /tmp/workspace | |
| DATA_DIR: /tmp/data | |
| WORK_DIR: /tmp/work | |
| VIDEO_DIR: /tmp/video | |
| DB_INIT_DIR: /tmp/db-init | |
| run: | | |
| docker compose -f docker-compose-release.yml config --quiet \ | |
| && echo "✅ docker-compose-release.yml valid" | |
| # ── 2. Build React UI ─────────────────────────────────── | |
| build-ui: | |
| name: Build UI | |
| runs-on: ubuntu-latest | |
| needs: lint | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - run: npm install | |
| - name: Build React UI | |
| run: npx cross-env OMNIBIOAI_DEV_MODE=false npm run build:ui | |
| - name: Verify dist | |
| run: | | |
| test -f dist/index.html || (echo "❌ dist/index.html missing" && exit 1) | |
| echo "✅ UI built — $(du -sh dist | cut -f1)" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: ui-dist | |
| path: dist/ | |
| retention-days: 1 | |
| # ── 3. Build Linux x64 (AppImage + DEB + RPM) ────────── | |
| build-linux-x64: | |
| name: Build Linux x64 | |
| runs-on: ubuntu-latest | |
| needs: build-ui | |
| if: github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - run: npm install | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ui-dist | |
| path: dist/ | |
| - name: Install system deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| libarchive-tools fakeroot rpm alien | |
| - name: Build Linux x64 | |
| run: npx electron-builder --linux AppImage deb rpm --x64 --publish onTag | |
| env: | |
| CSC_IDENTITY_AUTO_DISCOVERY: false | |
| OMNIBIOAI_DEV_MODE: false | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify | |
| run: | | |
| ls -lh release/ | |
| echo "✅ Linux x64 packages built" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-x64 | |
| path: | | |
| release/*.AppImage | |
| release/*.deb | |
| release/*.rpm | |
| retention-days: 7 | |
| # ── 4. Build Linux ARM64 (AppImage + DEB + RPM) ───────── | |
| build-linux-arm64: | |
| name: Build Linux ARM64 | |
| runs-on: ubuntu-latest | |
| needs: build-ui | |
| if: github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - run: npm install | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ui-dist | |
| path: dist/ | |
| # Required: set up QEMU so electron-builder can cross-compile to ARM64 | |
| - name: Set up QEMU for ARM64 cross-compilation | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: arm64 | |
| - name: Install system deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| libarchive-tools fakeroot rpm alien | |
| - name: Build Linux ARM64 | |
| run: npx electron-builder --linux AppImage deb rpm --arm64 --publish onTag | |
| env: | |
| CSC_IDENTITY_AUTO_DISCOVERY: false | |
| OMNIBIOAI_DEV_MODE: false | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify | |
| run: | | |
| ls -lh release/ | |
| echo "✅ Linux ARM64 packages built" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-arm64 | |
| path: | | |
| release/*arm64*.AppImage | |
| release/*arm64*.deb | |
| release/*.aarch64.rpm | |
| retention-days: 7 | |
| # ── 5. Build macOS (DMG arm64 + x64) ─────────────────── | |
| build-mac: | |
| name: Build macOS DMG | |
| runs-on: macos-latest | |
| needs: build-ui | |
| if: github.event_name == 'push' | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - run: npm install | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ui-dist | |
| path: dist/ | |
| - name: Build DMG (arm64 + x64) | |
| run: npx electron-builder --mac dmg --x64 --arm64 --publish onTag | |
| env: | |
| CSC_IDENTITY_AUTO_DISCOVERY: false | |
| OMNIBIOAI_DEV_MODE: false | |
| ELECTRON_GET_USE_PROXY: true | |
| GLOBAL_AGENT_HTTPS_PROXY: "" | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify | |
| run: | | |
| ls -lh release/*.dmg | |
| echo "✅ macOS DMGs built" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mac-dmg | |
| path: release/*.dmg | |
| retention-days: 7 | |
| # ── 6. Build Windows EXE ──────────────────────────────── | |
| build-windows: | |
| name: Build Windows EXE | |
| runs-on: windows-latest | |
| needs: build-ui | |
| if: github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - run: npm install | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ui-dist | |
| path: dist/ | |
| - name: Build NSIS installer | |
| run: npx electron-builder --win nsis --publish onTag | |
| env: | |
| CSC_IDENTITY_AUTO_DISCOVERY: false | |
| OMNIBIOAI_DEV_MODE: false | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify | |
| shell: pwsh | |
| run: | | |
| Get-ChildItem release/*.exe | Format-List Name, Length | |
| Write-Host "✅ Windows installer built" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-installer | |
| path: release/*.exe | |
| retention-days: 7 | |
| # ── 7. GitHub Release (tags only) ─────────────────────── | |
| release: | |
| name: Create GitHub Release | |
| runs-on: ubuntu-latest | |
| needs: [build-linux-x64, build-linux-arm64, build-mac, build-windows] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # needed for changelog generation | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: linux-x64 | |
| path: artifacts/linux-x64/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: linux-arm64 | |
| path: artifacts/linux-arm64/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: mac-dmg | |
| path: artifacts/mac/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: windows-installer | |
| path: artifacts/windows/ | |
| # Include docker-compose-release.yml and .env.example in the release | |
| # so users can run the stack without cloning the repo | |
| - name: Stage stack config files | |
| run: | | |
| cp docker-compose-release.yml artifacts/ | |
| cp .env.example artifacts/ | |
| - name: List all release artifacts | |
| run: | | |
| find artifacts/ -type f | sort | |
| echo "✅ All artifacts staged" | |
| - name: Generate checksums | |
| run: | | |
| cd artifacts | |
| find . -type f \( -name "*.AppImage" -o -name "*.deb" -o -name "*.rpm" \ | |
| -o -name "*.dmg" -o -name "*.exe" \ | |
| -o -name "docker-compose-release.yml" -o -name ".env.example" \) \ | |
| | sort | xargs sha256sum > SHA256SUMS.txt | |
| cat SHA256SUMS.txt | |
| - name: Extract changelog for this version | |
| id: changelog | |
| run: | | |
| VERSION=${GITHUB_REF_NAME#v} | |
| NOTES=$(awk "/^## \[${VERSION}\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md) | |
| echo "notes<<EOF" >> $GITHUB_OUTPUT | |
| echo "$NOTES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: "OmniBioAI Studio ${{ github.ref_name }}" | |
| prerelease: ${{ contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }} | |
| generate_release_notes: false | |
| body: ${{ steps.changelog.outputs.notes }} | |
| files: | | |
| artifacts/linux-x64/*.AppImage | |
| artifacts/linux-x64/*.deb | |
| artifacts/linux-x64/*.rpm | |
| artifacts/linux-arm64/*.AppImage | |
| artifacts/linux-arm64/*.deb | |
| artifacts/linux-arm64/*.rpm | |
| artifacts/mac/*.dmg | |
| artifacts/windows/*.exe | |
| artifacts/docker-compose-release.yml | |
| artifacts/.env.example | |
| artifacts/SHA256SUMS.txt | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |