Skip to content

Create Release Candidate #138

Create Release Candidate

Create Release Candidate #138

name: Create Release Candidate
on:
workflow_dispatch:
inputs:
release_type:
description: 'Type of release increment (patch, minor, major)'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
jobs:
build:
runs-on: windows-latest
permissions:
contents: write
outputs:
new_version: ${{ steps.get_version.outputs.new_version }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
- name: Get Latest Tag and Git Log
shell: bash
run: |
LATEST_TAG=$(git describe --tags --abbrev=0)
echo "Latest Tag: $LATEST_TAG"
GIT_LOG=$(git log "${LATEST_TAG}..HEAD" --no-merges --oneline)
echo "Git Log:"
echo "$GIT_LOG"
echo "GIT_LOG<<EOF" >> $GITHUB_ENV
echo "$GIT_LOG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Display Git Log
shell: bash
run: |
echo "Git Log since last tag:"
echo "$GIT_LOG"
- name: Generate Release Notes
id: generate_release_notes
shell: bash
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
# --- Debug: Show jq info ---
echo "ℹ️ Using jq from path: $(which jq)"
echo "ℹ️ jq version: $(jq --version)"
# --- Debug: Show raw input ---
echo "📜 Raw GIT_LOG:"
echo "$GIT_LOG"
echo ""
# Use pre-installed Chocolatey jq
export PATH="/c/ProgramData/Chocolatey/bin:$PATH"
# Define system prompt
SYSTEM_PROMPT="You are a helpful assistant who creates user-friendly release notes for open-source applications such as games and clip recorders. Your task is to transform raw update logs into concise and easy-to-understand release notes. Use a casual, direct tone and avoid overly technical language and details that are not important for the end user. Please merge changes if you think they are the same method/function that changed. Avoid wrapping the final release notes in a Markdown code block. Non techy and do not include things like chore or refactor if it doesn't do anything for the user! Do not include the text Release Notes in the beginning. Do not say thanks in the end. Also, "
# --- Debug: Show escaped content ---
echo "🔧 Escaping content..."
ESCAPED_SYSTEM=$(jq -Rs . <<< "$SYSTEM_PROMPT")
ESCAPED_LOG=$(jq -Rs . <<< "$GIT_LOG")
echo "🔒 Escaped System Prompt:"
echo "$ESCAPED_SYSTEM"
echo ""
echo "🔒 Escaped Git Log:"
echo "$ESCAPED_LOG"
echo ""
# Build JSON payload
JSON_PAYLOAD=$(jq -n \
--arg model "gpt-4o" \
--argjson system "$ESCAPED_SYSTEM" \
--argjson log "$ESCAPED_LOG" \
'{
"model": $model,
"messages": [
{"role": "system", "content": $system},
{"role": "user", "content": $log}
]
}')
# --- Debug: Show final payload ---
echo "📦 JSON Payload:"
echo "$JSON_PAYLOAD"
echo ""
# Make API call
echo "📡 Making API request to OpenAI..."
RESPONSE=$(curl -s -X POST "https://api.openai.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d "$JSON_PAYLOAD")
# --- Debug: Show raw response ---
echo "📨 Raw API Response:"
echo "$RESPONSE"
echo ""
# Extract release notes
RELEASE_NOTES=$(echo "$RESPONSE" | jq -r '.choices[0].message.content')
# --- Debug: Show final output ---
echo "🎉 Generated Release Notes:"
echo "$RELEASE_NOTES"
echo ""
- name: Determine Version
id: get_version
shell: pwsh
run: |
$tags = git tag
if ($tags -ne $null -and $tags.Count -gt 0) {
$latestTag = (git describe --tags --abbrev=0 2>$null) -replace '^v', ''
if (-not $latestTag) {
$latestTag = "0.0.0"
}
} else {
$latestTag = "0.0.0"
}
$latestTag = [string]$latestTag
# Check if the latest tag is a release candidate
$isReleaseCandidate = $latestTag -match '(.+)-rc\.(.+)'
$baseVersion = $latestTag
$rcNumber = 0
if ($isReleaseCandidate) {
# Extract base version and RC number
$baseVersion = $Matches[1]
$rcNumber = [int]$Matches[2]
}
$versionParts = $baseVersion.Split('.')
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2]
$releaseType = "${{ github.event.inputs.release_type }}"
# If it's the same base version, increment RC number
# Otherwise, increment version according to release type
if ($isReleaseCandidate) {
$rcNumber++
$newVersion = "$baseVersion-rc.$rcNumber"
} else {
switch ($releaseType) {
"major" { $major++; $minor=0; $patch=0 }
"minor" { $minor++; $patch=0 }
"patch" { $patch++ }
default { $patch++ }
}
$newVersion = "$major.$minor.$patch-rc.1"
}
echo "new_version=$newVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8
echo "new_version=$newVersion" >> $env:GITHUB_OUTPUT
- name: Configure Git User
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
shell: pwsh
- name: Install vpk as .NET Global Tool
run: |
dotnet tool install -g vpk
$env:PATH += ";$env:USERPROFILE\.dotnet\tools"
shell: pwsh
- name: Update Frontend version
working-directory: ./Frontend
shell: pwsh
run: |
$content = Get-Content package.json -Raw
$packageJson = Get-Content package.json -Raw | ConvertFrom-Json
$packageJson.version = $env:new_version
$packageJson | ConvertTo-Json -Depth 100 | Set-Content package.json -NoNewline
Write-Host "Updated version: $(Select-String -Path package.json -Pattern 'version')"
- name: Install Frontend dependencies
working-directory: ./Frontend
run: bun install --frozen-lockfile
- name: Build Frontend
working-directory: ./Frontend
run: bun run build
- name: Move Frontend Build to Resources/wwwroot
run: |
$source = "./Frontend/dist"
$destination = "./Resources/wwwroot"
if (-Not (Test-Path -Path $destination)) { New-Item -ItemType Directory -Path $destination -Force }
Remove-Item -Path "$destination\*" -Recurse -Force
Copy-Item -Path "$source\*" -Destination $destination -Recurse -Force
shell: pwsh
- name: Publish the App
run: dotnet publish -c Release --self-contained -r win-x64 -o publish
shell: pwsh
- name: Package with vpk
run: vpk pack -u Segra -v ${{ env.new_version }} -p ./publish -e Segra.exe -o ./output --packTitle "Segra" --noPortable
shell: pwsh
- name: Create a Git Tag
run: |
git tag v${{ env.new_version }}
git push origin v${{ env.new_version }}
shell: pwsh
- name: Upload Release Artifact
uses: actions/upload-artifact@v4
with:
name: Segra
path: ./output
retention-days: 1
pre-release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download Build Artifact
uses: actions/download-artifact@v4
with:
name: Segra
- name: Create GitHub Release (Pre-Release)
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ needs.build.outputs.new_version }}
release_name: "Release v${{ needs.build.outputs.new_version }}"
body: ""
draft: false
prerelease: true
- name: Upload Setup File
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Segra-win-Setup.exe
asset_name: Segra-win-Setup.exe
asset_content_type: application/octet-stream
- name: Upload RELEASES File
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./RELEASES
asset_name: RELEASES
asset_content_type: text/plain
- name: Upload releases.win.json
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./releases.win.json
asset_name: releases.win.json
asset_content_type: application/json
- name: Upload assets.win.json
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./assets.win.json
asset_name: assets.win.json
asset_content_type: application/json
- name: Upload nupkg
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Segra-${{ needs.build.outputs.new_version }}-full.nupkg
asset_name: Segra-${{ needs.build.outputs.new_version }}-full.nupkg
asset_content_type: application/json