Nightly Build #102
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: Nightly Build | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| schedule: | |
| - cron: '0 0 * * *' # Runs every day at midnight UTC | |
| jobs: | |
| check: | |
| name: Determine Build Necessity | |
| runs-on: ubuntu-latest | |
| outputs: | |
| proceed: ${{ steps.check.outputs.proceed }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get the last nightly commit | |
| id: last_nightly | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const releases = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 100 | |
| }); | |
| const nightlyRelease = releases.data.find(release => release.tag_name.includes('nightly') || release.name.includes('Nightly')); | |
| if (nightlyRelease) { | |
| const tagName = nightlyRelease.tag_name; | |
| const tag = await github.rest.git.getRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: `tags/${tagName}` | |
| }); | |
| const commitSha = tag.data.object.sha; | |
| return commitSha; | |
| } else { | |
| return null; | |
| } | |
| - name: Check the proceed condition | |
| id: check | |
| run: | | |
| LAST_NIGHTLY_COMMIT="${{ steps.last_nightly.outputs.result }}" | |
| CURRENT_COMMIT="${GITHUB_SHA}" | |
| echo "Last nightly commit: $LAST_NIGHTLY_COMMIT" | |
| echo "Current commit: $CURRENT_COMMIT" | |
| if [ -z "$LAST_NIGHTLY_COMMIT" ]; then | |
| echo "No previous nightly release found. Proceeding with build." | |
| echo "proceed=true" >> $GITHUB_OUTPUT | |
| elif [ "$LAST_NIGHTLY_COMMIT" != "$CURRENT_COMMIT" ]; then | |
| echo "New commits found since last nightly release. Proceeding with build." | |
| echo "proceed=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "No new commits since last nightly release. Skipping build." | |
| echo "proceed=false" >> $GITHUB_OUTPUT | |
| fi | |
| build: | |
| name: Nightly Build on ${{ matrix.os }} | |
| needs: check | |
| if: needs.check.outputs.proceed == 'true' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [windows-latest, macos-latest, ubuntu-latest] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| submodules: recursive | |
| - uses: actions/checkout@v5 | |
| with: | |
| repository: floooh/sokol-tools-bin | |
| ref: "a06f19929ff8f9824ec6dd87c21329b1f205809e" | |
| path: sokol-tools-bin | |
| fetch-depth: 1 | |
| - name: Setup sokol-shdc | |
| shell: bash | |
| run: | | |
| if [[ "$RUNNER_OS" == "Windows" ]]; then | |
| TARGET_DIR="C:/Windows/System32" | |
| SHDC_BINARY="sokol-shdc.exe" | |
| FIND_PATH="bin/win32" | |
| elif [[ "$RUNNER_OS" == "macOS" ]]; then | |
| TARGET_DIR="/usr/local/bin" | |
| SHDC_BINARY="sokol-shdc" | |
| FIND_PATH="bin/osx_arm64" | |
| else # Linux | |
| TARGET_DIR="/usr/local/bin" | |
| SHDC_BINARY="sokol-shdc" | |
| FIND_PATH="bin/linux" | |
| fi | |
| echo "Setting up sokol-tools from sokol-tools-bin/$FIND_PATH" | |
| find sokol-tools-bin/$FIND_PATH -name $SHDC_BINARY -exec cp {} $TARGET_DIR \; | |
| $SHDC_BINARY -h | |
| - uses: yuchanns/actions-luamake@v1 | |
| with: | |
| luamake-version: "5bedfce66f075a9f68b1475747738b81b3b41c25" | |
| - name: Install Dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential \ | |
| libgl1-mesa-dev libglu1-mesa-dev libx11-dev \ | |
| libxrandr-dev libxi-dev libxxf86vm-dev libxcursor-dev \ | |
| libasound2-dev libfontconfig1-dev | |
| - name: Build (Windows) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| id: build-windows | |
| run: | | |
| luamake clean | |
| luamake precompile | |
| luamake soluna | |
| $SOLUNA_BINARY = "soluna.exe" | |
| $RENAME_BINARY = "soluna-windows-amd64.exe" | |
| $SOLUNA_PATH = (Get-ChildItem -Path "bin" -Name $SOLUNA_BINARY -Recurse | Select-Object -First 1) | |
| Copy-Item "bin\$SOLUNA_PATH" "bin\$RENAME_BINARY" | |
| echo "SOLUNA_PATH=bin/$RENAME_BINARY" >> $env:GITHUB_OUTPUT | |
| echo "SOLUNA_BINARY=$RENAME_BINARY" >> $env:GITHUB_OUTPUT | |
| - name: Build (Unix) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| id: build-unix | |
| run: | | |
| luamake precompile | |
| luamake soluna | |
| if [[ "$RUNNER_OS" == "Linux" ]]; then | |
| RENAME_BINARY="soluna-linux-amd64" | |
| elif [[ "$RUNNER_OS" == "macOS" ]]; then | |
| RENAME_BINARY="soluna-macos-arm64" | |
| else | |
| echo "Unsupported OS: $RUNNER_OS" | |
| exit 1 | |
| fi | |
| SOLUNA_BINARY="soluna" | |
| SOLUNA_PATH=$(find bin -name $SOLUNA_BINARY | head -n 1) | |
| cp "$SOLUNA_PATH" "bin/$RENAME_BINARY" | |
| echo "SOLUNA_PATH=bin/$RENAME_BINARY" >> $GITHUB_OUTPUT | |
| echo "SOLUNA_BINARY=$RENAME_BINARY" >> $GITHUB_OUTPUT | |
| - uses: actions/upload-artifact@v4 | |
| name: Upload | |
| if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' | |
| with: | |
| name: "soluna-${{ runner.os }}-${{ runner.os == 'Windows' && steps.build-windows.outputs.SOLUNA_BINARY || steps.build-unix.outputs.SOLUNA_BINARY }}" | |
| if-no-files-found: "error" | |
| path: "${{ runner.os == 'Windows' && steps.build-windows.outputs.SOLUNA_PATH || steps.build-unix.outputs.SOLUNA_PATH }}" | |
| overwrite: "true" | |
| release: | |
| name: Create Nightly Release | |
| needs: [check, build] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v5 | |
| with: | |
| path: artifacts | |
| - name: Prepare release assets | |
| run: | | |
| mkdir -p release-assets | |
| find artifacts -type f -name "soluna*" -exec cp {} release-assets/ \; | |
| ls -la release-assets/ | |
| - name: Delete existing nightly releases | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const releases = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 100 | |
| }); | |
| for (const release of releases.data) { | |
| if (release.tag_name.includes('nightly') || release.name.includes('Nightly')) { | |
| console.log(`Deleting release: ${release.tag_name}`); | |
| try { | |
| await github.rest.repos.deleteRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: release.id | |
| }); | |
| try { | |
| await github.rest.git.deleteRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: `tags/${release.tag_name}` | |
| }); | |
| } catch (error) { | |
| console.log(`Tag ${release.tag_name} might not exist or already deleted`); | |
| } | |
| } catch (error) { | |
| console.log(`Failed to delete release ${release.tag_name}: ${error.message}`); | |
| } | |
| } | |
| } | |
| - name: Create nightly release | |
| id: create-release | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5); | |
| const commitSha = context.sha.substring(0, 7); | |
| const tagName = 'nightly'; | |
| const releaseNotes = `🌙 **Nightly Build** | |
| **Build Information:** | |
| - **Commit:** \`${context.sha}\` | |
| - **Branch:** \`${context.ref.replace('refs/heads/', '')}\` | |
| - **Build Time:** \`${new Date().toISOString()}\` | |
| - **Workflow:** [${context.runId}](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) | |
| > ⚠️ **Note:** This is an automated nightly build. It may contain unstable features and bugs. | |
| > | |
| > 📦 **Previous nightly releases are automatically removed to keep the repository clean.`; | |
| const { data } = await github.rest.repos.createRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag_name: tagName, | |
| name: `Nightly Build (${timestamp})`, | |
| body: releaseNotes, | |
| prerelease: true, | |
| make_latest: 'false' | |
| }); | |
| console.log(`Created release: ${data.html_url}`); | |
| return data.id; | |
| - name: Upload release assets | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const releaseId = ${{ steps.create-release.outputs.result }}; | |
| const assetsDir = 'release-assets'; | |
| const files = fs.readdirSync(assetsDir); | |
| for (const file of files) { | |
| const filePath = path.join(assetsDir, file); | |
| const stats = fs.statSync(filePath); | |
| if (stats.isFile()) { | |
| console.log(`Uploading ${file}...`); | |
| const content = fs.readFileSync(filePath); | |
| await github.rest.repos.uploadReleaseAsset({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: releaseId, | |
| name: file, | |
| data: content | |
| }); | |
| console.log(`✅ Uploaded ${file}`); | |
| } | |
| } |