Merge branch 'develop' of github.com:ni/actor-framework into develop #11
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: Build VI Package | |
on: | |
push: | |
branches: | |
- main | |
- develop | |
- release-alpha/* | |
- release-beta/* | |
- release-rc/* | |
- hotfix/* | |
pull_request: | |
branches: | |
- main | |
- develop | |
- release-alpha/* | |
- release-beta/* | |
- release-rc/* | |
- hotfix/* | |
workflow_dispatch: | |
env: | |
DRAFT_RELEASE: true | |
USE_AUTO_NOTES: true | |
DISABLE_GPG_ON_FORKS: false | |
ATTACH_ARTIFACTS_TO_RELEASE: true | |
jobs: | |
build-release: | |
runs-on: [self-hosted, actorframework] | |
permissions: | |
contents: write | |
issues: read | |
pull-requests: read | |
steps: | |
######################################################################## | |
# A) Possibly disable GPG signing on forks | |
######################################################################## | |
- name: Possibly disable GPG signing on forks | |
if: ${{ env.DISABLE_GPG_ON_FORKS == 'true' }} | |
id: disable_signing | |
shell: pwsh | |
run: | | |
if ("${{ github.repository }}" -ne "ni/actor-framework") { | |
Write-Host "Detected a fork; disabling GPG signing..." | |
$currentCommitGpgsign = git config --global commit.gpgsign | |
if (-not $currentCommitGpgsign) { $currentCommitGpgsign = "" } | |
$currentTagGpgsign = git config --global tag.gpgsign | |
if (-not $currentTagGpgsign) { $currentTagGpgsign = "" } | |
"old_commit_gpgsign=$currentCommitGpgsign" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"old_tag_gpgsign=$currentTagGpgsign" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
git config --global commit.gpgsign false | |
git config --global tag.gpgsign false | |
} | |
else { | |
Write-Host "This is the official repo => no GPG changes." | |
"old_commit_gpgsign=" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"old_tag_gpgsign=" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
} | |
######################################################################## | |
# 1) Check out code (full depth) | |
######################################################################## | |
- name: Check out code | |
uses: actions/checkout@v3 | |
with: | |
persist-credentials: true | |
fetch-depth: 0 | |
######################################################################## | |
# 2) Determine bump type from labels (major/minor/patch), else none | |
######################################################################## | |
- name: Determine bump type | |
id: bump_type | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
if (context.event_name === 'pull_request') { | |
const labels = context.payload.pull_request.labels.map(l => l.name.toLowerCase()); | |
core.info(`Found labels on PR: ${labels.join(', ')}`); | |
let bump = 'none'; | |
if (labels.includes('major')) { | |
bump = 'major'; | |
} else if (labels.includes('minor')) { | |
bump = 'minor'; | |
} else if (labels.includes('patch')) { | |
bump = 'patch'; | |
} | |
core.setOutput('bump_type', bump); | |
} else { | |
core.setOutput('bump_type', 'none'); | |
} | |
######################################################################## | |
# 3) Commit-based build number | |
######################################################################## | |
- name: Determine build number | |
id: inc_build | |
shell: pwsh | |
run: | | |
git fetch --unshallow 2>$null || Write-Host "Already a full clone." | |
$commitCount = git rev-list --count HEAD | |
Write-Host "Commit-based build number => $commitCount" | |
"new_build_number=$commitCount" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
######################################################################## | |
# 4) Parse latest version tag, apply major/minor/patch if found | |
######################################################################## | |
- name: Compute version string | |
id: next_version | |
shell: pwsh | |
env: | |
BUMP_TYPE: ${{ steps.bump_type.outputs.bump_type }} | |
BUILD_NUMBER: ${{ steps.inc_build.outputs.new_build_number }} | |
run: | | |
Write-Host "Bump type: $($env:BUMP_TYPE)" | |
Write-Host "Build number: $($env:BUILD_NUMBER)" | |
$branchRef = $env:GITHUB_REF -replace '^refs/heads/', '' | |
Write-Host "Full branchRef: $branchRef" | |
# Find the last stable tag (fallback to 0.0.0 if none) | |
$latestTag = git describe --tags --abbrev=0 2>$null | |
if ([string]::IsNullOrEmpty($latestTag)) { | |
$baseMajor = 0 | |
$baseMinor = 0 | |
$basePatch = 0 | |
} | |
else { | |
$tagNoPrefix = $latestTag.TrimStart('v') | |
$versionPart = $tagNoPrefix -replace '-build.*','' | |
$baseMajor, $baseMinor, $basePatch = $versionPart.Split('.') | |
} | |
$newMajor = [int]$baseMajor | |
$newMinor = [int]$baseMinor | |
$newPatch = [int]$basePatch | |
# Apply label-based semantic bump | |
switch ($env:BUMP_TYPE) { | |
'major' { | |
$newMajor++ | |
$newMinor = 0 | |
$newPatch = 0 | |
} | |
'minor' { | |
$newMinor++ | |
$newPatch = 0 | |
} | |
'patch' { | |
$newPatch++ | |
} | |
'none' { } | |
} | |
# If alpha/beta/rc => generate pre-release suffix | |
$preSuffix = "" | |
if ($branchRef -like 'release-alpha/*') { | |
$countAlpha = git rev-list --count HEAD | |
if ([string]::IsNullOrEmpty($countAlpha)) { $countAlpha = 1 } | |
$preSuffix = "alpha.$countAlpha" | |
} | |
elseif ($branchRef -like 'release-beta/*') { | |
$countBeta = git rev-list --count HEAD | |
if ([string]::IsNullOrEmpty($countBeta)) { $countBeta = 1 } | |
$preSuffix = "beta.$countBeta" | |
} | |
elseif ($branchRef -like 'release-rc/*') { | |
$countRc = git rev-list --count HEAD | |
if ([string]::IsNullOrEmpty($countRc)) { $countRc = 1 } | |
$preSuffix = "rc.$countRc" | |
} | |
if ([string]::IsNullOrEmpty($preSuffix)) { | |
$version = "v$($newMajor).$($newMinor).$($newPatch)-build$($env:BUILD_NUMBER)" | |
$isPrerelease = "false" | |
} | |
else { | |
$version = "v$($newMajor).$($newMinor).$($newPatch)-$preSuffix-build$($env:BUILD_NUMBER)" | |
$isPrerelease = "true" | |
} | |
Write-Host "Computed version => $version" | |
"VERSION=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"IS_PRERELEASE=$isPrerelease" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"MAJOR=$newMajor" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"MINOR=$newMinor" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
"PATCH=$newPatch" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
######################################################################## | |
# 5) Build the icon editor VI package | |
######################################################################## | |
- name: Build the icon editor VI package | |
shell: pwsh | |
env: | |
MAJOR: ${{ steps.next_version.outputs.MAJOR }} | |
MINOR: ${{ steps.next_version.outputs.MINOR }} | |
PATCH: ${{ steps.next_version.outputs.PATCH }} | |
BUILD: ${{ steps.inc_build.outputs.new_build_number }} | |
COMMIT: ${{ github.sha }} | |
run: | | |
$repoRoot = $env:GITHUB_WORKSPACE | |
$scriptsFolder = Join-Path $repoRoot 'pipeline/scripts' | |
# Split the 'owner/repo' string to extract org and repository | |
$org, $repo = $env:GITHUB_REPOSITORY -split '/' | |
Write-Host "Building VI package => MAJOR=$($env:MAJOR), MINOR=$($env:MINOR), PATCH=$($env:PATCH), BUILD=$($env:BUILD)" | |
Write-Host "CompanyName => $org" | |
Write-Host "AuthorName => $repo" | |
# Call the updated Build.ps1 which now expects -CompanyName and -AuthorName | |
.\pipeline\scripts\Build.ps1 ` | |
-BasePath $repoRoot ` | |
-BasePathScripts $scriptsFolder ` | |
-Major $env:MAJOR ` | |
-Minor $env:MINOR ` | |
-Patch $env:PATCH ` | |
-Build $env:BUILD ` | |
-Commit $env:COMMIT ` | |
-CompanyName $org ` | |
-AuthorName $repo | |
######################################################################## | |
# 6) Capture the .vip file path as a step output | |
######################################################################## | |
- name: Discover .vip path | |
id: find_vip | |
shell: pwsh | |
run: | | |
$vipFile = Get-ChildItem -Path "builds" -Filter "*.vip" -ErrorAction Stop | Select-Object -First 1 | |
if (-not $vipFile) { | |
Write-Host "No .vip file found in builds!" | |
exit 1 | |
} | |
Write-Host "Discovered VIP File: $($vipFile.FullName)" | |
"vip_path=$($vipFile.FullName)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
######################################################################## | |
# 7) Upload ephemeral artifact (the .vip file) | |
######################################################################## | |
- name: Upload ephemeral artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.next_version.outputs.VERSION }} | |
path: ${{ steps.find_vip.outputs.vip_path }} | |
######################################################################## | |
# 8) Create & push tag (skip if it's a PR) | |
######################################################################## | |
- name: Create & push tag | |
if: ${{ github.event_name != 'pull_request' }} | |
shell: pwsh | |
run: | | |
$VERSION = "${{ steps.next_version.outputs.VERSION }}" | |
git config user.name "github-actions[bot]" | |
git config user.email "github-actions[bot]@users.noreply.github.com" | |
git tag -a $VERSION -m "Auto-tag by CI for $VERSION" | |
git push origin $VERSION | |
######################################################################## | |
# 9) Create GitHub Release (capture release_id) | |
######################################################################## | |
- name: Create GitHub Release | |
if: ${{ success() && github.event_name != 'pull_request' }} | |
id: create_release | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const versionTag = '${{ steps.next_version.outputs.VERSION }}'; | |
const draftRelease = (process.env.DRAFT_RELEASE || 'true').toLowerCase() === 'true'; | |
const useAutoNotes = (process.env.USE_AUTO_NOTES || 'true').toLowerCase() === 'true'; | |
const isPrerelease = (('${{ steps.next_version.outputs.IS_PRERELEASE }}' || '').toLowerCase() === 'true'); | |
const createParams = { | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
tag_name: versionTag, | |
name: versionTag, | |
draft: draftRelease, | |
prerelease: isPrerelease | |
}; | |
if (useAutoNotes) { | |
createParams.generate_release_notes = true; | |
} else { | |
createParams.body = "Reference local release notes or embed within .vip."; | |
} | |
const response = await github.rest.repos.createRelease(createParams); | |
core.setOutput("upload_url", response.data.upload_url); | |
core.setOutput("release_id", response.data.id); | |
core.info( | |
`Created release [draft=${draftRelease}, prerelease=${isPrerelease}] => ${versionTag}` | |
); | |
######################################################################## | |
# 10) Attach .vip file(s) to Release using github-script | |
######################################################################## | |
- name: Attach .vip file(s) to Release | |
if: ${{ success() && env.ATTACH_ARTIFACTS_TO_RELEASE == 'true' && github.event_name != 'pull_request' }} | |
uses: actions/github-script@v6 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const path = require('path'); | |
const releaseId = '${{ steps.create_release.outputs.release_id }}'; | |
if (!releaseId) { | |
core.warning("No release_id found; skipping attach."); | |
return; | |
} | |
const vipDir = path.join(process.env.GITHUB_WORKSPACE, 'builds'); | |
let vipFiles = []; | |
try { | |
vipFiles = fs.readdirSync(vipDir).filter(f => f.toLowerCase().endsWith('.vip')); | |
} catch (err) { | |
core.warning(`Could not read directory 'builds/VI Package': ${err.message}`); | |
return; | |
} | |
if (!vipFiles.length) { | |
core.warning("No .vip files found to attach."); | |
return; | |
} | |
core.info(`Discovered .vip files: ${vipFiles.join(', ')}`); | |
for (const vipFile of vipFiles) { | |
const fullPath = path.join(vipDir, vipFile); | |
const fileData = fs.readFileSync(fullPath); | |
core.info(`Uploading '${vipFile}' to release #${releaseId}...`); | |
await github.rest.repos.uploadReleaseAsset({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
release_id: parseInt(releaseId, 10), | |
name: vipFile, | |
data: fileData, | |
headers: { | |
'content-type': 'application/octet-stream', | |
'content-length': fileData.length | |
} | |
}); | |
core.info(`Successfully attached '${vipFile}'!`); | |
} | |
######################################################################## | |
# B) Re-enable GPG signing if it was disabled | |
######################################################################## | |
- name: Re-enable GPG signing (if disabled) | |
if: ${{ always() && env.DISABLE_GPG_ON_FORKS == 'true' }} | |
shell: pwsh | |
run: | | |
if ("${{ github.repository }}" -ne "ni/actor-framework") { | |
Write-Host "Restoring GPG signing..." | |
$oldCommitGpgsign = '${{ steps.disable_signing.outputs.old_commit_gpgsign }}' | |
$oldTagGpgsign = '${{ steps.disable_signing.outputs.old_tag_gpgsign }}' | |
if ($oldCommitGpgsign) { | |
git config --global commit.gpgsign $oldCommitGpgsign | |
} else { | |
git config --global --unset commit.gpgsign || Write-Host "commit.gpgsign wasn't originally set." | |
} | |
if ($oldTagGpgsign) { | |
git config --global tag.gpgsign $oldTagGpgsign | |
} else { | |
git config --global --unset tag.gpgsign || Write-Host "tag.gpgsign wasn't originally set." | |
} | |
} | |
else { | |
Write-Host "Official repo or DISABLE_GPG_ON_FORKS==false => no restore needed." | |
} |