From 6467bdfe7c776436c10fb3ed84a56bd7a47e09d0 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Fri, 21 Nov 2025 09:48:25 +0000 Subject: [PATCH] Add reusable build workflows and dev prereleases --- .github/workflows/build-and-upload.yml | 178 +++++++++++++++++++++++++ .github/workflows/dev-release.yml | 92 +++++++++++++ .github/workflows/release.yml | 148 +++----------------- packages/electron-app/package.json | 6 +- 4 files changed, 288 insertions(+), 136 deletions(-) create mode 100644 .github/workflows/build-and-upload.yml create mode 100644 .github/workflows/dev-release.yml diff --git a/.github/workflows/build-and-upload.yml b/.github/workflows/build-and-upload.yml new file mode 100644 index 00000000..639cfa34 --- /dev/null +++ b/.github/workflows/build-and-upload.yml @@ -0,0 +1,178 @@ +name: Build and Upload Binaries + +on: + workflow_call: + inputs: + version: + description: "Version to apply to workspace packages" + required: true + type: string + tag: + description: "Git tag to upload assets to" + required: true + type: string + release_name: + description: "Release name (unused here, for context)" + required: true + type: string + +permissions: + contents: write + +env: + NODE_VERSION: 20 + +jobs: + build-macos: + runs-on: macos-13 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ inputs.version }} + TAG: ${{ inputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + + - name: Set workspace versions + run: npm pkg set version=${VERSION} --workspaces --include-workspace-root + + - name: Install dependencies + run: npm ci --workspaces + + - name: Build macOS binaries + run: npm run build:mac --workspace @neuralnomads/codenomad-electron-app + + - name: Upload release assets + run: | + shopt -s nullglob + for file in packages/electron-app/release/*; do + [ -f "$file" ] || continue + case "$file" in + *.dmg|*.zip) + gh release upload "$TAG" "$file" --clobber + ;; + *) + echo "Skipping non-installer asset: $file" + ;; + esac + done + + build-windows: + runs-on: windows-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ inputs.version }} + TAG: ${{ inputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + + - name: Set workspace versions + run: npm pkg set version=${{ env.VERSION }} --workspaces --include-workspace-root + shell: bash + + - name: Install dependencies + run: npm ci --workspaces + + - name: Build Windows binaries + run: npm run build:win --workspace @neuralnomads/codenomad-electron-app + + - name: Upload release assets + shell: pwsh + run: | + Get-ChildItem -Path "packages/electron-app/release" -File | Where-Object { + $_.Name -match '\\.(exe|zip)$' + } | ForEach-Object { + gh release upload $env:TAG $_.FullName --clobber + } + + build-linux: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ inputs.version }} + TAG: ${{ inputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + + - name: Set workspace versions + run: npm pkg set version=${VERSION} --workspaces --include-workspace-root + + - name: Install dependencies + run: npm ci --workspaces + + - name: Build Linux binaries + run: npm run build:linux --workspace @neuralnomads/codenomad-electron-app + + - name: Upload release assets + run: | + shopt -s nullglob + for file in packages/electron-app/release/*; do + [ -f "$file" ] || continue + case "$file" in + *.AppImage|*.deb|*.tar.gz) + gh release upload "$TAG" "$file" --clobber + ;; + *) + echo "Skipping non-installer asset: $file" + ;; + esac + done + + build-linux-rpm: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ inputs.version }} + TAG: ${{ inputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + + - name: Install rpm packaging dependencies + run: | + sudo apt-get update + sudo apt-get install -y rpm ruby ruby-dev build-essential + sudo gem install --no-document fpm + + - name: Set workspace versions + run: npm pkg set version=${VERSION} --workspaces --include-workspace-root + + - name: Install project dependencies + run: npm ci --workspaces + + - name: Build Linux RPM binaries + run: npm run build:linux-rpm --workspace @neuralnomads/codenomad-electron-app + + - name: Upload RPM release assets + run: | + shopt -s nullglob + for file in packages/electron-app/release/*.rpm; do + [ -f "$file" ] || continue + gh release upload "$TAG" "$file" --clobber + done diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml new file mode 100644 index 00000000..1ac7d6c7 --- /dev/null +++ b/.github/workflows/dev-release.yml @@ -0,0 +1,92 @@ +name: Dev Release + +on: + workflow_dispatch: + inputs: + base_version: + description: "Base semver (e.g. 1.2.3)" + required: true + type: string + +permissions: + contents: write + +env: + NODE_VERSION: 20 + +jobs: + prepare-dev: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.versions.outputs.version }} + tag: ${{ steps.versions.outputs.tag }} + release_name: ${{ steps.versions.outputs.release_name }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Compute dev versions + id: versions + env: + BASE_VERSION: ${{ inputs.base_version }} + run: | + DEV_VERSION="${BASE_VERSION}-dev" + TIMESTAMP=$(date -u +%y%m%d-%H%M) + TAG="v${DEV_VERSION}-${TIMESTAMP}" + echo "version=$DEV_VERSION" >> "$GITHUB_OUTPUT" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + echo "release_name=$TAG" >> "$GITHUB_OUTPUT" + + - name: Create GitHub release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: ${{ steps.versions.outputs.tag }} + run: | + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists" + else + gh release create "$TAG" --title "$TAG" --generate-notes + fi + + build-and-upload: + needs: prepare-dev + uses: ./.github/workflows/build-and-upload.yml + with: + version: ${{ needs.prepare-dev.outputs.version }} + tag: ${{ needs.prepare-dev.outputs.tag }} + release_name: ${{ needs.prepare-dev.outputs.release_name }} + secrets: inherit + + publish-server: + needs: build-and-upload + runs-on: ubuntu-latest + env: + NODE_VERSION: 20 + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + VERSION: ${{ needs.prepare-dev.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + + - name: Set workspace versions + run: npm pkg set version=${VERSION} --workspaces --include-workspace-root + + - name: Install dependencies + run: npm ci --workspaces + + - name: Build server package + run: npm run build --workspace @neuralnomads/codenomad + + - name: Publish server package to dev tag + run: npm publish --workspace @neuralnomads/codenomad --access public --tag dev diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 606196da..2388c33b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,84 +63,21 @@ jobs: gh release create "$TAG" --title "CodeNomad v${VERSION}" --generate-notes fi - build-macos: + build-and-upload: needs: prepare-release - runs-on: macos-13 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v4 + uses: ./.github/workflows/build-and-upload.yml + with: + version: ${{ needs.prepare-release.outputs.version }} + tag: ${{ needs.prepare-release.outputs.tag }} + release_name: CodeNomad v${{ needs.prepare-release.outputs.version }} + secrets: inherit - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - - - name: Install dependencies - run: npm ci --workspaces - - - name: Build macOS binaries - run: npm run build:mac --workspace @codenomad/electron-app - - - name: Upload release assets - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ needs.prepare-release.outputs.tag }} - run: | - set -euo pipefail - shopt -s nullglob - for file in packages/electron-app/release/*; do - [ -f "$file" ] || continue - case "$file" in - *.dmg|*.zip) - gh release upload "$TAG" "$file" --clobber - ;; - *) - echo "Skipping non-installer asset: $file" - ;; - esac - done - - build-windows: - needs: prepare-release - runs-on: windows-latest - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - - - name: Install dependencies - run: npm ci --workspaces - - - name: Build Windows binaries - run: npm run build:win --workspace @codenomad/electron-app - - - name: Upload release assets - shell: pwsh - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ needs.prepare-release.outputs.tag }} - run: | - Get-ChildItem -Path "packages/electron-app/release" -File | Where-Object { - $_.Name -match '\.(exe|zip)$' - } | ForEach-Object { - gh release upload $env:TAG $_.FullName --clobber - } - - build-linux: - needs: prepare-release + publish-server: + needs: build-and-upload runs-on: ubuntu-latest env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_VERSION: 20 + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - name: Checkout uses: actions/checkout@v4 @@ -154,63 +91,8 @@ jobs: - name: Install dependencies run: npm ci --workspaces - - name: Build Linux binaries - run: npm run build:linux --workspace @codenomad/electron-app + - name: Build server package + run: npm run build --workspace @neuralnomads/codenomad - - name: Upload release assets - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ needs.prepare-release.outputs.tag }} - run: | - set -euo pipefail - shopt -s nullglob - for file in packages/electron-app/release/*; do - [ -f "$file" ] || continue - case "$file" in - *.AppImage|*.deb|*.tar.gz) - gh release upload "$TAG" "$file" --clobber - ;; - *) - echo "Skipping non-installer asset: $file" - ;; - esac - done - - build-linux-rpm: - needs: prepare-release - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - - - name: Install rpm packaging dependencies - run: | - sudo apt-get update - sudo apt-get install -y rpm ruby ruby-dev build-essential - sudo gem install --no-document fpm - - - name: Install project dependencies - run: npm ci --workspaces - - - name: Build Linux RPM binaries - run: npm run build:linux-rpm --workspace @codenomad/electron-app - - - name: Upload RPM release assets - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ needs.prepare-release.outputs.tag }} - run: | - set -euo pipefail - shopt -s nullglob - for file in packages/electron-app/release/*.rpm; do - [ -f "$file" ] || continue - gh release upload "$TAG" "$file" --clobber - done + - name: Publish server package + run: npm publish --workspace @neuralnomads/codenomad --access public --tag latest diff --git a/packages/electron-app/package.json b/packages/electron-app/package.json index c9c66572..68acd0f5 100644 --- a/packages/electron-app/package.json +++ b/packages/electron-app/package.json @@ -74,7 +74,7 @@ "arch": ["x64", "arm64", "universal"] } ], - "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", + "artifactName": "CodeNomadApp-${version}-${os}-${arch}.${ext}", "icon": "electron/resources/icon.icns" }, "dmg": { @@ -94,7 +94,7 @@ "arch": ["x64", "arm64"] } ], - "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", + "artifactName": "CodeNomadApp-${version}-${os}-${arch}.${ext}", "icon": "electron/resources/icon.ico" }, "nsis": { @@ -122,7 +122,7 @@ "arch": ["x64", "arm64"] } ], - "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", + "artifactName": "CodeNomadApp-${version}-${os}-${arch}.${ext}", "category": "Development", "icon": "electron/resources/icon.png" }