chore(release): 1.15.0 #40
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| jobs: | |
| create-release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Extract release notes and create release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG_NAME: ${{ github.ref_name }} | |
| run: | | |
| # Extract the current version's section from the committed CHANGELOG.md | |
| node -e " | |
| const fs = require('fs'); | |
| const log = fs.readFileSync('CHANGELOG.md', 'utf-8'); | |
| const tag = process.env.TAG_NAME; | |
| const sections = log.split(/^(?=##? \[)/m); | |
| const current = sections.find(s => s.includes(tag)); | |
| if (current) { | |
| // Remove the heading line, keep only the body | |
| const body = current.replace(/^##? .+\n+/, '').trim(); | |
| fs.writeFileSync('_RELEASE_NOTES.md', body); | |
| } else { | |
| fs.writeFileSync('_RELEASE_NOTES.md', ''); | |
| } | |
| " | |
| gh release create "$TAG_NAME" --title "$TAG_NAME" --notes-file _RELEASE_NOTES.md | |
| build: | |
| needs: create-release | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| build-args: --win | |
| - os: macos-latest | |
| build-args: --mac | |
| - os: ubuntu-latest | |
| build-args: --linux | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Azure login (Windows signing) | |
| if: runner.os == 'Windows' | |
| uses: azure/login@v3 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| allow-no-subscriptions: true | |
| - name: Build, package, and upload | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| AZURE_TENANT_ID: ${{ runner.os == 'Windows' && secrets.AZURE_TENANT_ID || '' }} | |
| AZURE_CLIENT_ID: ${{ runner.os == 'Windows' && secrets.AZURE_CLIENT_ID || '' }} | |
| AZURE_CLIENT_SECRET: ${{ runner.os == 'Windows' && secrets.AZURE_CLIENT_SECRET || '' }} | |
| run: | | |
| npx electron-vite build | |
| if [ "$RUNNER_OS" = "Windows" ]; then | |
| npx electron-builder ${{ matrix.build-args }} --publish always \ | |
| -c.win.azureSignOptions.endpoint="https://eus.codesigning.azure.net" \ | |
| -c.win.azureSignOptions.codeSigningAccountName="kudu-signing" \ | |
| -c.win.azureSignOptions.certificateProfileName="kudu-sign" \ | |
| -c.win.azureSignOptions.publisherName="Advent Development, Inc." | |
| else | |
| npx electron-builder ${{ matrix.build-args }} --publish always | |
| fi | |
| publish-choco: | |
| needs: build | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Get version from tag | |
| id: version | |
| shell: bash | |
| run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| - name: Download installer and compute checksum | |
| shell: pwsh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| $version = "${{ steps.version.outputs.version }}" | |
| $url = "https://github.com/AdventDevInc/kudu/releases/download/v$version/Kudu-Setup-$version.exe" | |
| Invoke-WebRequest -Uri $url -OutFile "Kudu-Setup-$version.exe" | |
| $hash = (Get-FileHash "Kudu-Setup-$version.exe" -Algorithm SHA256).Hash | |
| echo "CHECKSUM=$hash" >> $env:GITHUB_ENV | |
| - name: Update choco package files | |
| shell: pwsh | |
| run: | | |
| $version = "${{ steps.version.outputs.version }}" | |
| $nuspec = Get-Content choco/kudu.nuspec -Raw | |
| $nuspec = $nuspec -replace '<version>.+?</version>', "<version>$version</version>" | |
| $nuspec = $nuspec -replace 'tag/v.+?"', "tag/v$version`"" | |
| Set-Content choco/kudu.nuspec $nuspec | |
| $install = Get-Content choco/tools/chocolateyinstall.ps1 -Raw | |
| $install = $install -replace "\`$version = '.+?'", "`$version = '$version'" | |
| $install = $install -replace '__REPLACE_WITH_SHA256_HASH__|[A-Fa-f0-9]{64}', $env:CHECKSUM | |
| Set-Content choco/tools/chocolateyinstall.ps1 $install | |
| - name: Pack and push to Chocolatey | |
| shell: pwsh | |
| run: | | |
| choco pack choco/kudu.nuspec --out . | |
| choco push usekudu.${{ steps.version.outputs.version }}.nupkg --source "https://push.chocolatey.org/" --api-key "${{ secrets.CHOCOLATEY_API_KEY }}" | |
| virustotal-scan: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get version from tag | |
| id: version | |
| run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| - name: Download release artifacts | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| version="${{ steps.version.outputs.version }}" | |
| gh release download "v$version" --repo AdventDevInc/kudu --pattern "Kudu-Setup-*.exe" --pattern "Kudu-*.dmg" --pattern "Kudu-*.AppImage" --pattern "Kudu-*.deb" --dir artifacts/ | |
| - name: Scan with VirusTotal | |
| env: | |
| VT_API_KEY: ${{ secrets.VIRUSTOTAL_API_KEY }} | |
| run: | | |
| results="" | |
| for file in artifacts/*; do | |
| filename=$(basename "$file") | |
| filesize=$(stat -c%s "$file") | |
| echo "Uploading $filename ($filesize bytes) to VirusTotal..." | |
| if [ "$filesize" -gt 33554432 ]; then | |
| # Files > 32MB need the large-file upload URL | |
| echo " Using large-file upload flow..." | |
| upload_url=$(curl -s --request GET \ | |
| --url "https://www.virustotal.com/api/v3/files/upload_url" \ | |
| --header "x-apikey: $VT_API_KEY" | jq -r '.data') | |
| else | |
| upload_url="https://www.virustotal.com/api/v3/files" | |
| fi | |
| response=$(curl -s --request POST \ | |
| --url "$upload_url" \ | |
| --header "x-apikey: $VT_API_KEY" \ | |
| --form "file=@$file") | |
| analysis_id=$(echo "$response" | jq -r '.data.id') | |
| if [ "$analysis_id" != "null" ] && [ -n "$analysis_id" ]; then | |
| echo " Analysis ID: $analysis_id" | |
| results="$results- **$filename**: https://www.virustotal.com/gui/file-analysis/$analysis_id\n" | |
| else | |
| echo " Failed to upload: $response" | |
| results="$results- **$filename**: upload failed\n" | |
| fi | |
| # VirusTotal free API rate limit: 4 requests/minute | |
| sleep 20 | |
| done | |
| echo "## VirusTotal Scan Results" > vt_report.md | |
| echo "" >> vt_report.md | |
| echo -e "$results" >> vt_report.md | |
| - name: Append scan results to release notes | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| version="${{ steps.version.outputs.version }}" | |
| existing=$(gh release view "v$version" --repo AdventDevInc/kudu --json body -q .body) | |
| vt_report=$(cat vt_report.md) | |
| gh release edit "v$version" --repo AdventDevInc/kudu --notes "${existing} | |
| ${vt_report}" | |
| publish-winget: | |
| needs: build | |
| runs-on: windows-latest | |
| steps: | |
| - name: Get version from tag | |
| id: version | |
| shell: bash | |
| run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| - name: Update winget manifest | |
| shell: pwsh | |
| run: | | |
| $version = "${{ steps.version.outputs.version }}" | |
| $url = "https://github.com/AdventDevInc/kudu/releases/download/v$version/Kudu-Setup-$version.exe" | |
| Invoke-WebRequest -Uri "https://aka.ms/wingetcreate/latest" -OutFile wingetcreate.exe | |
| .\wingetcreate.exe update AdventDevelopmentInc.Kudu --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version $version |