Skip to content

chore(cicd): if for automerge #403

chore(cicd): if for automerge

chore(cicd): if for automerge #403

Workflow file for this run

name: Dev solution checks then package TELBlazor.Components and trigger TELBlazor-DevShowCase deployment
on:
push:
branches-ignore:
- 'main'
- 'master'
# We currently dont intend to test the showcase per package bump so wont run for package bumps
# we will run on the collected bumps merging though
- 'dependabot/**'
workflow_dispatch:
permissions:
contents: write
actions: write
env:
# Permission
GITHUB_TOKEN: ${{ secrets.NUGETKEY }}
TEL_GIT_PACKAGES_TOKEN: ${{ secrets.NUGETKEY }}
GITHUB_USERNAME: "Phil-NHS"
# Nuget Set Up
NUGET_PACKAGES_OUTPUT_PATH: ${{ github.workspace }}/CICDPackageLocation
LOCAL_PACKAGES_PATH : ${{ github.workspace }}/CICDPackageLocation
TEL_GIT_PACKAGE_SOURCE: "https://nuget.pkg.github.com/TechnologyEnhancedLearning/index.json"
# Build Set Up
USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE: false
jobs:
dev-call-reusable-ci-checks-workflow:
name: Dev Run CI checks
uses: ./.github/workflows/reuseable-ci-checks.yml
with:
runall: true
# Commit being run against
base_sha: ${{ github.event.before }}
head_sha: ${{ github.event.after }}
secrets:
# Dev
UNITTESTS_APPSETTINGS_DEVELOPMENT: ${{ secrets.UNITTESTS_APPSETTINGS_DEVELOPMENT }}
WASMSTATICCLIENT_APPSETTINGS_DEVELOPMENT: ${{ secrets.WASMSTATICCLIENT_APPSETTINGS_DEVELOPMENT }}
WASMSERVERHOSTCLIENT_APPSETTINGS_DEVELOPMENT: ${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_DEVELOPMENT }}
WASMSERVERHOST_APPSETTINGS_DEVELOPMENT: ${{ secrets.WASMSERVERHOST_APPSETTINGS_DEVELOPMENT }}
# Token
TEL_GIT_PACKAGES_TOKEN: ${{secrets.NUGETKEY }}
# Prod
# UNITTESTS_APPSETTINGS_PRODUCTION: ${{ secrets.UNITTESTS_APPSETTINGS_PRODUCTION }}
# WASMSTATICCLIENT_APPSETTINGS_PRODUCTION: ${{ secrets.WASMSTATICCLIENT_APPSETTINGS_PRODUCTION }}
# WASMSERVERHOSTCLIENT_APPSETTINGS_PRODUCTION: ${{ secrets.WASMSERVERHOSTCLIENT_APPSETTINGS_PRODUCTION }}
# WASMSERVERHOST_APPSETTINGS_PRODUCTION: ${{ secrets.WASMSERVERHOST_APPSETTINGS_PRODUCTION }}
# Now we've done due diligence
# The checks have been allowed to run if the workflow fails so if there a multiple fails we know.
# We do not proceed from the point if there is a fail.
# Hence explicit "if" and "needs"
generate-dev-semantic-version:
name: Generate dev semantic version
if: success()
needs: [dev-call-reusable-ci-checks-workflow]
runs-on: ubuntu-latest
outputs:
dev-package-version: ${{ steps.set_dev_semantic_version.outputs.dev-semantic-version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for Semantic Release to analyze commit history
- name: Install semantic release packages
run: |
echo "Installing semantic-release packages..."
npm install -D \
semantic-release \
@semantic-release/changelog \
@semantic-release/git \
@semantic-release/commit-analyzer \
@semantic-release/release-notes-generator \
@semantic-release/github
echo "Semantic Release packages installed."
npm ls --depth=0 # Debug: List installed packages
# Configured with .releaseserc
# Dry run we are not versioning the repo
- name: Run dev semantic version (None Blocking)
id: detect_semantic_version
run: |
echo "error catch run of semver first to get any error detail on config issues"
set +e
SEMVER_OUTPUT_RAW_ERROR_CHECK=$(npx semantic-release --dry-run 2> /tmp/semantic-release-errors.log)
STATUS_ERROR_CHECK=$?
# Now you can check the status and log the error messages if an error occurred
if [ $STATUS_ERROR_CHECK -ne 0 ]; then
echo "❌ Semantic release failed with exit code $STATUS_ERROR_CHECK."
echo "❌ Error output:"
cat /tmp/semantic-release-errors.log
else
echo "✅ Semantic Ouput success : $SEMVER_OUTPUT_RAW_ERROR_CHECK "
echo "✅ Error on success : $STATUS_ERROR_CHECK"
fi
set -e
echo "running semantic-release"
semver_output_raw=$(npx semantic-release --dry-run 2>&1)
status=$?
# Now you can check the status and log the error messages if an error occurred
if [ $STATUS -ne 0 ]; then
echo "Semantic release failed with exit code $STATUS."
echo "Error output:"
cat /tmp/semantic-release-errors.log
fi
echo "status = $STATUS"
echo "$SEMVER_OUTPUT_RAW"
# Get fallback version by grabbing the git tag dropping the first character, the "v", or use hardcoded fallback
FALLBACK_VERSION=$(git describe --tags --abbrev=0 2>/dev/null | cut -c2- || echo "0.0.0-version-not-found")
echo "FALLBACK_VERSION=$FALLBACK_VERSION"
set +e
# Check what's in the output
GREP_NO_CHANGES=$(echo "$SEMVER_OUTPUT_RAW" | grep -q 'There are no relevant changes' && echo "true" || echo "false")
GREP_WOULD_PUBLISH=$(echo "$SEMVER_OUTPUT_RAW" | grep -q 'Published release' && echo "true" || echo "false")
echo "GREP_NO_CHANGES=$GREP_NO_CHANGES"
echo "GREP_WOULD_PUBLISH=$GREP_WOULD_PUBLISH"
set -e
# Check for no changes and set DEV_SEMVER_VERSION accordingly
if echo "$SEMVER_OUTPUT_RAW" | grep -q 'There are no relevant changes'; then
DEV_SEMVER_VERSION="$FALLBACK_VERSION"
echo "No relevant changes found - DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION"
echo "DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION" >> $GITHUB_ENV
# Check if version bump expected
elif echo "$SEMVER_OUTPUT_RAW" | grep -q 'Published release'; then
# Extract the actual version
DEV_SEMVER_VERSION=$(echo "$SEMVER_OUTPUT_RAW" | grep -oP 'Published release \K[^\s]+' || echo "extract-failed")
echo "Version change detected - DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION"
echo "version change required true"
echo "DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION" >> $GITHUB_ENV
# Fallback
else
echo " ⚠️ Neither 'no changes' nor 'publish version' found. (using fallback)."
DEV_SEMVER_VERSION="$FALLBACK_VERSION"
echo "DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION"
echo "DEV_SEMVER_VERSION=$DEV_SEMVER_VERSION" >> $GITHUB_ENV
fi
- name: Rename Semver Version with branch date time dev
id: set_dev_semantic_version
run: |
# DEV_SEMVER_VERSION="${{ steps.detect_semantic_version.outputs.DEV_SEMVER_VERSION }}"
echo "Dev Semantic Version Output = $DEV_SEMVER_VERSION"
# In development, we always package and update the website—even if there’s no version change.
# This ensures the CI process runs consistently and the latest code is deployed.
# It's especially useful when squashing commits, as it guarantees the package is still rebuilt and published.
timestamp=$(date +"%y%m%d-%H%M")
echo "Timestamp $timestamp"
full_version="${DEV_SEMVER_VERSION}-${timestamp}"
echo "extracted version $full_version"
echo "dev-semantic-version=$full_version" >> $GITHUB_OUTPUT
build-telblazor-dev-package-and-publish:
if: success()
name: Build dev package and publish
needs: [generate-dev-semantic-version, dev-call-reusable-ci-checks-workflow]
runs-on: ubuntu-latest
env:
DEV_TELBLAZOR_PACKAGE_VERSION: ${{ needs.generate-dev-semantic-version.outputs.dev-package-version }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Debug version output DEV_TELBLAZOR_PACKAGE_VERSION
run: echo "Extracted Version $DEV_TELBLAZOR_PACKAGE_VERSION "
- 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 supersede 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
#CI is an install that adheres to package-lock
- 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 TELBlazor.Components (it publishes on build)
run: |
dotnet build TELBlazor.Components -c Release \
/p:TELBlazorPackageVersion=$DEV_TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=false
- name: Publish to TechnologyEnhancedLearning as a Dev Package
run: |
dotnet nuget push "$NUGET_PACKAGES_OUTPUT_PATH/TELBlazor.Components.*.nupkg" \
--source $TEL_GIT_PACKAGE_SOURCE \
--api-key $TEL_GIT_PACKAGES_TOKEN \
--skip-duplicate
trigger-gh-pages-telblazor-devshowcase-workflow:
name: Create artifact and provide it to TelBlazor-DevShowCase repo and its gh-page trigger
if: success() #not needed but being explicit
needs: [build-telblazor-dev-package-and-publish, generate-dev-semantic-version, dev-call-reusable-ci-checks-workflow]
runs-on: ubuntu-latest
env:
DEV_TELBLAZOR_PACKAGE_VERSION: ${{ needs.generate-dev-semantic-version.outputs.dev-package-version }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Clean solution
run: |
echo "Cleaning the solution..."
dotnet clean TELBlazor.sln
- 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%|$TEL_GIT_PACKAGE_SOURCE|g" nuget.config
sed -i "s|%GITHUB_USERNAME%|$GITHUB_USERNAME|g" nuget.config
sed -i "s|%TEL_GIT_PACKAGES_TOKEN%|$TEL_GIT_PACKAGES_TOKEN|g" nuget.config
- name: debug DEV_TELBLAZOR_PACKAGE_VERSION
run: |
echo "DEV_TELBLAZOR_PACKAGE_VERSION $DEV_TELBLAZOR_PACKAGE_VERSION"
- 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 supersede the locks
run: |
echo "Listing packages.lock.json files:"
find . -name "packages.lock.json" -type f -print
echo ""
echo "Deleting packages.lock.json files:"
find . -name "packages.lock.json" -type f -exec rm -f {} \;
echo "Listing packages.lock.json files:"
find . -name "packages.lock.json" -type f -print
- 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 solution without generating new package
run: |
dotnet build TELBlazor.sln -c Release \
/p:TELBlazorPackageVersion=$DEV_TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=true
- name: Publish WasmStaticClient
run: |
dotnet publish ./TELBlazor.Components.ShowCase.WasmStaticClient/TELBlazor.Components.ShowCase.WasmStaticClient.csproj --configuration Release \
/p:TELBlazorPackageVersion=$DEV_TELBLAZOR_PACKAGE_VERSION \
/p:NugetPackagesOutputPath=$NUGET_PACKAGES_OUTPUT_PATH \
/p:UseTELBlazorComponentsProjectReference=$USE_TEL_BLAZOR_COMPONENTS_PROJECT_REFERENCE \
/p:DisablePackageGeneration=true
#include hidden so we get jekyll
- name: Creating artifact of publish folder for test gh page workflow
uses: actions/upload-artifact@v4
with:
name: published-telblazor-components-showcase-wasmstaticclient-using-dev-package-${{env.DEV_TELBLAZOR_PACKAGE_VERSION}}
include-hidden-files: true
path: |
./docs
./docs/.nojekyll # explicitly include the .nojekyll file
retention-days: 90
- name: Get artifact location
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"
# Change this line to select by name instead of position
ARTIFACT_URL=$(echo "$ARTIFACT_LIST" | jq -r '.artifacts[] | select(.name=="published-telblazor-components-showcase-wasmstaticclient-using-dev-package-${{env.DEV_TELBLAZOR_PACKAGE_VERSION}}") | .url')
# Echo the artifact URL to confirm
echo "Artifact URL: $ARTIFACT_URL"
echo "artifact_url=$ARTIFACT_URL" >> $GITHUB_ENV
- name: Trigger workflow in TELBlazor-DevShowCase repo
run: |
repo_owner="TechnologyEnhancedLearning"
repo_name="TELBlazor-DevShowCase"
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\"}}"