CI Pipeline (Composite) #70
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: CI Pipeline (Composite) | |
# Builds, tests, and packages the Icon Editor. See docs/ci-workflows.md for details. | |
permissions: | |
contents: read | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
on: | |
push: | |
branches: | |
- main | |
- develop | |
- release-alpha/* | |
- release-beta/* | |
- release-rc/* | |
- feature/* | |
- hotfix/* | |
- issue-* | |
pull_request: | |
branches: | |
- main | |
- develop | |
- release-alpha/* | |
- release-beta/* | |
- release-rc/* | |
- feature/* | |
- hotfix/* | |
- issue-* | |
types: | |
- opened | |
- synchronize | |
- reopened | |
- ready_for_review | |
workflow_dispatch: # manual trigger | |
jobs: | |
# Skip subsequent jobs unless the branch is associated with an issue in progress | |
issue-status: | |
name: Verify Issue Status | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
issues: read | |
outputs: | |
proceed: ${{ steps.check.outputs.proceed }} | |
steps: | |
- name: Determine if CI should run | |
id: check | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const branch = context.payload.pull_request?.head.ref ?? | |
context.ref.replace('refs/heads/', ''); | |
const match = branch.match(/(?:^|\/)issue-(\d+)/); | |
if (!match) { | |
core.setOutput('proceed', 'false'); | |
const msg = `Branch '${branch}' is not issue-specific. CI will be skipped.`; | |
core.info(msg); | |
fs.appendFileSync( | |
process.env.GITHUB_STEP_SUMMARY, | |
[ | |
'### Issue Status', | |
'', | |
`Branch ${branch} is not associated with an issue.`, | |
'CI will be skipped.', | |
'' | |
].join('\n') | |
); | |
return; | |
} | |
const issueNumber = parseInt(match[1], 10); | |
// Skip CI when a 'NoCI' label is present | |
const prNumber = context.payload.pull_request?.number; | |
let hasNoCILabel = false; | |
if (prNumber) { | |
hasNoCILabel = context.payload.pull_request.labels.some(l => l.name === 'NoCI'); | |
} else { | |
const { data: prs } = await github.rest.pulls.list({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
head: `${context.repo.owner}:${branch}`, | |
state: 'open' | |
}); | |
hasNoCILabel = prs.some(pr => pr.labels.some(l => l.name === 'NoCI')); | |
} | |
if (hasNoCILabel) { | |
core.setOutput('proceed', 'false'); | |
const msg = `Branch '${branch}' is labeled 'NoCI'. CI will be skipped.`; | |
core.info(msg); | |
fs.appendFileSync( | |
process.env.GITHUB_STEP_SUMMARY, | |
[ | |
'### Issue Status', | |
'', | |
msg, | |
'' | |
].join('\n') | |
); | |
return; | |
} | |
const query = ` | |
query($owner:String!, $repo:String!, $number:Int!){ | |
repository(owner:$owner, name:$repo){ | |
issue(number:$number){ | |
projectItems(first:10){ | |
nodes{ | |
fieldValueByName(name: "Status"){ | |
... on ProjectV2ItemFieldSingleSelectValue{ | |
name | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
`; | |
const variables = { | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
number: issueNumber | |
}; | |
const result = await github.graphql(query, variables); | |
const nodes = result.repository.issue.projectItems.nodes; | |
const status = | |
nodes.map(n => n.fieldValueByName?.name).find(Boolean) ?? | |
'Unknown'; | |
const proceed = status === 'In Progress'; | |
core.info(`Issue #${issueNumber} status: ${status}`); | |
core.info(`Proceed with CI: ${proceed}`); | |
const summary = [ | |
'### Issue Status', | |
'', | |
`- Branch: ${branch}`, | |
`- Issue: #${issueNumber}`, | |
`- Status: **${status}**`, | |
`- CI will ${proceed ? 'run' : 'be skipped'}` | |
].join('\n'); | |
fs.appendFileSync( | |
process.env.GITHUB_STEP_SUMMARY, | |
`${summary}\n` | |
); | |
core.setOutput('proceed', proceed ? 'true' : 'false'); | |
# Detect if VIPC files changed to decide whether dependencies must be installed | |
changes: | |
name: Detect VIPC changes | |
needs: issue-status | |
if: needs.issue-status.outputs.proceed == 'true' | |
runs-on: ubuntu-latest | |
outputs: | |
vipc: ${{ steps.filter.outputs.vipc }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- id: filter | |
uses: dorny/paths-filter@v3 | |
with: | |
filters: | | |
vipc: | |
- '**/*.vipc' | |
apply-deps: | |
name: Apply VIPC Dependencies | |
needs: changes | |
if: needs.changes.outputs.vipc == 'true' | |
runs-on: self-hosted-windows-lv | |
strategy: | |
matrix: | |
include: | |
- lv-version: "2021" | |
bitness: "32" | |
- lv-version: "2021" | |
bitness: "64" | |
- lv-version: "2023" | |
bitness: "64" | |
steps: | |
- uses: ./.github/actions/apply-vipc | |
with: | |
minimum_supported_lv_version: ${{ matrix['lv-version'] }} | |
vip_lv_version: ${{ matrix['lv-version'] }} | |
supported_bitness: ${{ matrix.bitness }} | |
relative_path: ${{ github.workspace }} | |
version: | |
name: Compute Version | |
needs: issue-status | |
if: needs.issue-status.outputs.proceed == 'true' | |
runs-on: self-hosted-windows-lv | |
outputs: | |
VERSION: ${{ steps.compute.outputs.VERSION }} | |
MAJOR: ${{ steps.compute.outputs.MAJOR }} | |
MINOR: ${{ steps.compute.outputs.MINOR }} | |
PATCH: ${{ steps.compute.outputs.PATCH }} | |
BUILD: ${{ steps.compute.outputs.BUILD }} | |
IS_PRERELEASE: ${{ steps.compute.outputs.IS_PRERELEASE }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- id: compute | |
uses: ./.github/actions/compute-version | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
missing-in-project-check: | |
name: Test Missing-In-Project Action on Windows | |
needs: [changes, apply-deps] | |
if: ${{ needs.changes.result == 'success' && (needs.apply-deps.result == 'success' || needs.apply-deps.result == 'skipped') }} | |
runs-on: self-hosted-windows-lv | |
strategy: | |
fail-fast: false | |
matrix: | |
lv-version: ["2021"] | |
bitness: ["64","32"] | |
steps: | |
- uses: ./.github/actions/missing-in-project | |
with: | |
lv-ver: ${{ matrix.lv-version }} | |
arch: ${{ matrix.bitness }} | |
project-file: "lv_icon_editor.lvproj" | |
test: | |
name: Run Unit Tests | |
needs: [changes, missing-in-project-check] | |
runs-on: ${{ matrix.os == 'windows' && 'self-hosted-windows-lv' || 'self-hosted-linux-lv' }} | |
strategy: | |
matrix: | |
os: [windows] | |
lv-version: ["2021"] | |
bitness: ["64","32"] | |
fail-fast: false | |
steps: | |
- uses: ./.github/actions/run-unit-tests | |
with: | |
minimum_supported_lv_version: ${{ matrix['lv-version'] }} | |
supported_bitness: ${{ matrix.bitness }} | |
build-ppl: | |
name: Build ${{ matrix.bitness }}-bit Packed Library | |
needs: [test, version] | |
runs-on: self-hosted-windows-lv | |
permissions: | |
contents: read | |
actions: write | |
strategy: | |
matrix: | |
bitness: [32, 64] | |
include: | |
- bitness: 32 | |
suffix: x86 | |
- bitness: 64 | |
suffix: x64 | |
steps: | |
- uses: ./.github/actions/build-lvlibp | |
with: | |
minimum_supported_lv_version: 2021 | |
supported_bitness: ${{ matrix.bitness }} | |
relative_path: ${{ github.workspace }} | |
major: ${{ needs.version.outputs.MAJOR }} | |
minor: ${{ needs.version.outputs.MINOR }} | |
patch: ${{ needs.version.outputs.PATCH }} | |
build: ${{ needs.version.outputs.BUILD }} | |
commit: ${{ github.sha }} | |
- uses: ./.github/actions/close-labview | |
with: | |
minimum_supported_lv_version: 2021 | |
supported_bitness: ${{ matrix.bitness }} | |
- uses: ./.github/actions/rename-file | |
with: | |
current_filename: ${{ github.workspace }}/resource/plugins/lv_icon.lvlibp | |
new_filename: ${{ github.workspace }}/resource/plugins/lv_icon_${{ matrix.suffix }}.lvlibp | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: lv_icon_${{ matrix.suffix }}.lvlibp | |
path: resource/plugins/lv_icon_${{ matrix.suffix }}.lvlibp | |
build-vi-package: | |
name: Build VI Package | |
needs: [build-ppl, version] | |
runs-on: self-hosted-windows-lv | |
permissions: | |
contents: read | |
actions: read | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Generate release notes | |
uses: ./.github/actions/generate-release-notes | |
# output_path defaults to Tooling/deployment/release_notes.md | |
- uses: actions/download-artifact@v4 | |
with: | |
path: resource/plugins | |
pattern: lv_icon_*.lvlibp | |
merge-multiple: true | |
- name: Generate display information JSON | |
id: display-info | |
shell: pwsh | |
run: | | |
$info = @{ | |
"Package Version" = @{ | |
"major" = ${{ needs.version.outputs.MAJOR }} | |
"minor" = ${{ needs.version.outputs.MINOR }} | |
"patch" = ${{ needs.version.outputs.PATCH }} | |
"build" = ${{ needs.version.outputs.BUILD }} | |
} | |
"Product Name" = "" | |
"Company Name" = "${{ github.repository_owner }}" | |
"Author Name (Person or Company)" = "${{ github.event.repository.name }}" | |
"Product Homepage (URL)" = "" | |
"Legal Copyright" = "" | |
"License Agreement Name" = "" | |
"Product Description Summary" = "" | |
"Product Description" = "" | |
"Release Notes - Change Log" = "" | |
} | |
$json = $info | ConvertTo-Json -Depth 5 -Compress | |
"json=$json" >> $Env:GITHUB_OUTPUT | |
- uses: ./.github/actions/modify-vipb-display-info | |
with: | |
supported_bitness: 64 | |
relative_path: ${{ github.workspace }} | |
vipb_path: .github/actions/build-vi-package/NI Icon editor.vipb | |
minimum_supported_lv_version: 2023 | |
labview_minor_revision: 3 | |
major: ${{ needs.version.outputs.MAJOR }} | |
minor: ${{ needs.version.outputs.MINOR }} | |
patch: ${{ needs.version.outputs.PATCH }} | |
build: ${{ needs.version.outputs.BUILD }} | |
commit: ${{ github.sha }} | |
release_notes_file: ${{ github.workspace }}/Tooling/deployment/release_notes.md | |
display_information_json: ${{ steps.display-info.outputs.json }} | |
- uses: ./.github/actions/build-vi-package | |
with: | |
supported_bitness: 64 | |
minimum_supported_lv_version: 2023 | |
labview_minor_revision: 3 | |
major: ${{ needs.version.outputs.MAJOR }} | |
minor: ${{ needs.version.outputs.MINOR }} | |
patch: ${{ needs.version.outputs.PATCH }} | |
build: ${{ needs.version.outputs.BUILD }} | |
commit: ${{ github.sha }} | |
release_notes_file: ${{ github.workspace }}/Tooling/deployment/release_notes.md | |
display_information_json: ${{ steps.display-info.outputs.json }} | |
- uses: ./.github/actions/close-labview | |
with: | |
minimum_supported_lv_version: 2023 | |
supported_bitness: 64 | |
- name: Upload VI Package | |
uses: actions/upload-artifact@v4 | |
with: | |
name: vi-package | |
path: builds/VI Package/*.vip |