Skip to content

chore(release): check #11

chore(release): check

chore(release): check #11

name: Reusable CI Checks
on:
workflow_dispatch:
workflow_call:
inputs:
runall:
required: false
type: boolean
default: false
base_sha:
required: false
type: string
head_sha:
required: false
type: string
secrets:
UNITTESTS_APPSETTINGS_DEVELOPMENT:
required: true
WASMSTATICCLIENT_APPSETTINGS_DEVELOPMENT:
required: true
WASMSERVERHOSTCLIENT_APPSETTINGS_DEVELOPMENT:
required: true
WASMSERVERHOST_APPSETTINGS_DEVELOPMENT:
required: true
UNITTESTS_APPSETTINGS_PRODUCTION:
required: true
WASMSTATICCLIENT_APPSETTINGS_PRODUCTION:
required: true
WASMSERVERHOSTCLIENT_APPSETTINGS_PRODUCTION:
required: true
WASMSERVERHOST_APPSETTINGS_PRODUCTION:
required: true
TEL_GIT_PACKAGES_TOKEN:
required: true
env:
# Permission
TEL_GIT_PACKAGES_TOKEN: ${{ secrets.TEL_GIT_PACKAGES_TOKEN }}
# Nuget Set Up
NUGET_PACKAGES_OUTPUT_PATH: ${{ github.workspace }}/CICDPackageLocation
LOCAL_PACKAGES_PATH: ${{ github.workspace }}/CICDPackageLocation
# Build Set Up
# May need coverlet.collector xplat if using the packaged version to test
USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE: true
# Check Dummy Data
TELBLAZOR_PACKAGE_VERSION: "0.0.0-ci-checks"
jobs:
# Build Package
# Build Solution useing package
reuseable-ci-checks-solution-build:
name: Check solution builds as Release
runs-on: ubuntu-latest
continue-on-error: ${{ inputs.runall }}
outputs:
status: ${{ job.status }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Replace nuget.config with CI template
run: |
rm -f nuget.config
cp nuget.config.cicd nuget.config
- name: Replace local environment variable in nuget config because cant provide it as a parameter
run: |
sed -i "s|%TEL_BLAZOR_PACKAGE_SOURCE%|$LOCAL_PACKAGES_PATH|g" nuget.config
- name: Create appsettings development from secrets
run: |
declare -A paths
paths["./TELBlazor.Components.UnitTests/appsettings.Development.json"]='${{ secrets.UNITTESTS_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.WasmStaticClient/wwwroot/appsettings.Development.json"]='${{ secrets.WASMSTATICCLIENT_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client/wwwroot/appsettings.Development.json"]='${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/appsettings.Development.json"]='${{ secrets.WASMSERVERHOST_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.UnitTests/appsettings.Production.json"]='${{ secrets.UNITTESTS_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.WasmStaticClient/wwwroot/appsettings.Production.json"]='${{ secrets.WASMSTATICCLIENT_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client/wwwroot/appsettings.Production.json"]='${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/appsettings.Production.json"]='${{ secrets.WASMSERVERHOST_APPSETTINGS_PRODUCTION }}'
for path in "${!paths[@]}"; do
mkdir -p "$(dirname "$path")"
printf '%s' "${paths[$path]}" > "$path"
done
- name: Clean lock files because the newly generated package file will superseed the locks
run: |
find . -name "packages.lock.json" -type f -exec rm -f {} \;
- name: Set up Node.js so we have gulp for retrieving TEL Frontend Css
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install npm packages so we have gulp for retrieving TEL Frontend Css
run: npm ci
- name: Install wasm-tools workload (wasm-tools used for delinking so can test against optimised client wasm using TELBlazor package)
run: dotnet workload install wasm-tools --skip-manifest-update --source https://api.nuget.org/v3/index.json
- name: Build and create package locally
run: |
dotnet build TELBlazor.Components -c Release \
/p:TELBlazorPackageVersion=$TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=false
- name: Build solution without generating new package
run: |
dotnet build TELBlazor.sln -c Release \
/p:TELBlazorPackageVersion=$TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=true
reuseable-ci-checks-branch-name-check:

Check failure on line 135 in .github/workflows/reuseable-ci-checks.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/reuseable-ci-checks.yml

Invalid workflow file

You have an error in your yaml syntax on line 135
name: Check branch names
if: success() || failure()
continue-on-error: ${{ inputs.runall }}
outputs:
status: ${{ job.status }}
runs-on: ubuntu-latest
# Checkout so can get access to the file
- name: Checkout repository
uses: actions/checkout@v4
steps:
- name: Validate Branch Name
run: |
echo "📂 GITHUB_WORKSPACE is: $GITHUB_WORKSPACE"
echo "📂 Current working directory is: $(pwd)"
echo "📂 Listing files in current dir:"
ls
ls -alh
echo "📂 Listing files in workspace root:"
ls -alh "$GITHUB_WORKSPACE"
#BRANCH_NAME="${GITHUB_HEAD_REF}"
BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
echo "Validating branch name: $BRANCH_NAME"
# Read allowed branch patterns from .releaserc.json
RELEASERC_PATH="${{ github.workspace }}/.releaserc.json"
echo "Using releaserc at: $RELEASERC_PATH"
ALLOWED_BRANCHES=$(jq -r '.branches[].name' $RELEASERC_PATH)
VALID=false
for pattern in $ALLOWED_BRANCHES; do
# Convert wildcard * into regex
REGEX="^${pattern//\*/.*}$"
if [[ "$BRANCH_NAME" =~ $REGEX ]]; then
VALID=true
break
fi
done
# Always allow dependabot branches for CI
# Semver will ignore the branch but will bump the collected dependabot changes branch
if [[ "$BRANCH_NAME" =~ ^dependabot/ ]]; then
echo "✅ Branch is a dependabot branch its not for release or versioning but for merging into the dependabot collection branch"
VALID=true
fi
if [ "$VALID" = true ]; then
echo "✅ Branch name is valid"
else
echo "❌ Invalid branch name: $BRANCH_NAME"
echo "Allowed branch patterns:"
echo "$ALLOWED_BRANCHES"
exit 1
fi
# qqqq drop
# if [[ "$BRANCH_NAME" =~ ^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|sample|security|config|bugfix|hotfix)-[a-zA-Z0-9._/-]+$ ]] || [[ "$BRANCH_NAME" == "master" ]]; then
# echo "✅ Branch name is valid"
# else
# echo "❌ Invalid branch name: $BRANCH_NAME"
# echo "Branch names must follow one of the allowed prefixes:"
# echo " build-*, feat-*, fix-*, bugfix-*, hotfix-*, build-*, chore-*, ci-*, docs-*, perf-*, refactor-*, revert-*, style-*, test-*, sample-*, security-*, config-*, bugfix-*, hotfix-*"
# exit 1
# fi
reuseable-ci-checks-commitlint:
name: Check commit names
runs-on: ubuntu-latest
if: success() || failure()
continue-on-error: ${{ inputs.runall }}
outputs:
status: ${{ job.status }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
with:
configFile: .commitlintrc.json
# Only set from/to if inputs are provided, otherwise let action use defaults
from: ${{ inputs.base_sha != '' && inputs.base_sha || null }}
to: ${{ inputs.head_sha != '' && inputs.head_sha || null }}
reuseable-ci-e2e-unit-tests:
name: E2E Unit threshold and code report trigger
timeout-minutes: 60
runs-on: ubuntu-latest
if: success() || failure()
continue-on-error: ${{ inputs.runall }}
outputs:
status: ${{ job.status }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Replace nuget.config with CI template
run: |
rm -f nuget.config
cp nuget.config.cicd nuget.config
- name: Replace local environment variable in nuget config because cant provide it as a parameter
run: |
sed -i "s|%TEL_BLAZOR_PACKAGE_SOURCE%|$LOCAL_PACKAGES_PATH|g" nuget.config
- name: Clean lock files because the newly generated package file will superseed the locks
run: |
find . -name "packages.lock.json" -type f -exec rm -f {} \;
- name: Create appsettings development from secrets
run: |
declare -A paths
paths["./TELBlazor.Components.UnitTests/appsettings.Development.json"]='${{ secrets.UNITTESTS_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.WasmStaticClient/wwwroot/appsettings.Development.json"]='${{ secrets.WASMSTATICCLIENT_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client/wwwroot/appsettings.Development.json"]='${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/appsettings.Development.json"]='${{ secrets.WASMSERVERHOST_APPSETTINGS_DEVELOPMENT }}'
paths["./TELBlazor.Components.UnitTests/appsettings.Production.json"]='${{ secrets.UNITTESTS_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.WasmStaticClient/wwwroot/appsettings.Production.json"]='${{ secrets.WASMSTATICCLIENT_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost.Client/wwwroot/appsettings.Production.json"]='${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_PRODUCTION }}'
paths["./TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/TELBlazor.Components.ShowCase.E2ETests.WasmServerHost/appsettings.Production.json"]='${{ secrets.WASMSERVERHOST_APPSETTINGS_PRODUCTION }}'
for path in "${!paths[@]}"; do
mkdir -p "$(dirname "$path")"
printf '%s' "${paths[$path]}" > "$path"
done
- name: Set up Node.js so we have gulp for retrieving TEL Frontend Css
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install npm packages so we have gulp for retrieving TEL Frontend Css
run: npm ci
- name: Install ReportGenerator
run: dotnet tool restore
- name: Install wasm-tools workload (wasm-tools used for delinking so can test against optimised client wasm using TELBlazor package)
run: dotnet workload install wasm-tools --skip-manifest-update --source https://api.nuget.org/v3/index.json
- name: Build and create package locally
run: |
dotnet build TELBlazor.Components -c Release \
/p:TELBlazorPackageVersion=$TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=false
- name: Build solution without generating new package
run: |
dotnet build TELBlazor.sln -c Release \
/p:TELBlazorPackageVersion=$TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=true
- name: Ensure browsers are installed
run: pwsh TELBlazor.Components.ShowCase.E2ETests/bin/Release/net8.0/playwright.ps1 install --with-deps
- name: Run tests with coverage threshold check
id: unit_e2e_tests
run: |
dotnet test --no-build --no-restore -c Release \
/p:TELBlazorPackageVersion=$TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=true
continue-on-error: true
- name: Generate Coverage Report
run: |
dotnet reportgenerator \
-reports:"**/AllTestResults/**/coverage.cobertura.xml" \
-targetdir:CoverageReport \
-reporttypes:"Html;XmlSummary"
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: CoverageReport
- name: Get artifact location
env:
# requires local set env
GH_TOKEN: ${{ secrets.TEL_GIT_PACKAGES_TOKEN }}
run: |
# Get the artifact list for the current workflow run
ARTIFACT_LIST=$(gh api "repos/TechnologyEnhancedLearning/TELBlazor/actions/runs/${GITHUB_RUN_ID}/artifacts")
# Echo the entire artifact list for debugging purposes
echo "Artifact List: $ARTIFACT_LIST"
ARTIFACT_URL=$(echo "$ARTIFACT_LIST" | jq -r '.artifacts[] | select(.name=="coverage-report") | .url')
# Echo the artifact URL to confirm
echo "Artifact URL: $ARTIFACT_URL"
echo "artifact_url=$ARTIFACT_URL" >> $GITHUB_ENV
- name: Trigger workflow in TELBlazor-CodeReport repo
run: |
repo_owner="TechnologyEnhancedLearning"
repo_name="TELBlazor-CodeReport"
event_type="artifact_ready"
# Trigger the workflow
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $TEL_GIT_PACKAGES_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/$repo_owner/$repo_name/dispatches \
-d "{\"event_type\": \"$event_type\", \"client_payload\": {\"artifact_url\": \"$artifact_url\"}}"
- name: Fail job if test failed after report is generated
if: steps.unit_e2e_tests.outcome != 'success'
run: |
echo "{{steps.unit_e2e_tests.outcome }}"
echo "❌ One or more steps failed."
exit 1
reuseable-ci-checks-check-for-failed-jobs:
name: Check for failures
if: ${{ inputs.runall }}
needs:
- reuseable-ci-checks-solution-build
- reuseable-ci-checks-branch-name-check
- reuseable-ci-checks-commitlint
- reuseable-ci-e2e-unit-tests
runs-on: ubuntu-latest
steps:
- name: Check Job Results
run: |
echo "Solution Build: ${{ needs.reuseable-ci-checks-solution-build.outputs.status }}"
echo "Branch Name Check: ${{ needs.reuseable-ci-checks-branch-name-check.outputs.status }}"
echo "Commit Lint Check: ${{ needs.reuseable-ci-checks-commitlint.outputs.status }}"
echo "Tests: ${{ needs.reuseable-ci-e2e-unit-tests.outputs.status }}"
# Check if any job is not success (failure, cancelled, skipped)
if [[ "${{ needs.reuseable-ci-checks-solution-build.outputs.status }}" != "success" || \
"${{ needs.reuseable-ci-checks-branch-name-check.outputs.status }}" != "success" || \
"${{ needs.reuseable-ci-checks-commitlint.outputs.status }}" != "success" || \
"${{ needs.reuseable-ci-e2e-unit-tests.outputs.status }}" != "success" ]]; then
echo "❌ One or more jobs failed."
exit 1
fi
continue-on-error: false