Fix webapp deploy workflow errors and warnings #103
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: Deploy WebApps (All frameworks) | |
| on: | |
| pull_request: | |
| paths: | |
| - "examples/Web Apps/Framework Examples/**" | |
| - ".github/workflows/webapp-deploy.yml" | |
| push: | |
| branches: | |
| - "**" | |
| paths: | |
| - "examples/Web Apps/Framework Examples/**" | |
| - ".github/workflows/webapp-deploy.yml" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| generate-node-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| is-empty: ${{ steps.set-matrix.outputs.is-empty }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Generate Node apps matrix | |
| id: set-matrix | |
| run: | | |
| BASE_DIR="examples/Web Apps/Framework Examples" | |
| APPS=() | |
| for framework_dir in "$BASE_DIR"/*; do | |
| if [ -d "$framework_dir" ]; then | |
| FRAMEWORK="$(basename "$framework_dir")" | |
| if [[ "$FRAMEWORK" == "Blazor" ]]; then | |
| continue | |
| fi | |
| for app_dir in "$framework_dir"/*; do | |
| if [ -d "$app_dir" ]; then | |
| APPS+=("$FRAMEWORK/$(basename "$app_dir")") | |
| fi | |
| done | |
| fi | |
| done | |
| if [ ${#APPS[@]} -eq 0 ]; then | |
| MATRIX_JSON="[]" | |
| else | |
| MATRIX_JSON=$(printf '%s\n' "${APPS[@]}" | jq -R . | jq -cs .) | |
| fi | |
| echo "matrix=$MATRIX_JSON" >> "$GITHUB_OUTPUT" | |
| echo "Generated Node matrix: $MATRIX_JSON" | |
| if [[ "$MATRIX_JSON" == "[]" ]]; then | |
| echo "is-empty=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "is-empty=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| generate-blazor-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| is-empty: ${{ steps.set-matrix.outputs.is-empty }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Generate Blazor apps matrix | |
| id: set-matrix | |
| run: | | |
| BASE_DIR="examples/Web Apps/Framework Examples" | |
| APPS=() | |
| for framework_dir in "$BASE_DIR"/*; do | |
| if [ -d "$framework_dir" ]; then | |
| FRAMEWORK="$(basename "$framework_dir")" | |
| if [[ "$FRAMEWORK" != "Blazor" ]]; then | |
| continue | |
| fi | |
| for app_dir in "$framework_dir"/*; do | |
| if [ -d "$app_dir" ]; then | |
| APPS+=("$FRAMEWORK/$(basename "$app_dir")") | |
| fi | |
| done | |
| fi | |
| done | |
| if [ ${#APPS[@]} -eq 0 ]; then | |
| MATRIX_JSON="[]" | |
| else | |
| MATRIX_JSON=$(printf '%s\n' "${APPS[@]}" | jq -R . | jq -cs .) | |
| fi | |
| echo "matrix=$MATRIX_JSON" >> "$GITHUB_OUTPUT" | |
| echo "Generated Blazor matrix: $MATRIX_JSON" | |
| if [[ "$MATRIX_JSON" == "[]" ]]; then | |
| echo "is-empty=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "is-empty=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| build-node: | |
| needs: generate-node-matrix | |
| if: needs.generate-node-matrix.outputs.is-empty != 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| app_dir: ${{ fromJSON(needs.generate-node-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Parse Node app | |
| run: | | |
| APP_DIR="examples/Web Apps/Framework Examples/${{ matrix.app_dir }}" | |
| APP_NAME="$(echo "${{ matrix.app_dir }}" | tr '/' '-')" | |
| echo "APP_DIR=$APP_DIR" >> $GITHUB_ENV | |
| echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24.x | |
| - name: Install Node dependencies | |
| working-directory: ${{ env.APP_DIR }} | |
| run: npm ci | |
| - name: Lint Node app | |
| working-directory: ${{ env.APP_DIR }} | |
| run: npm run lint | |
| - name: Build Node app | |
| working-directory: ${{ env.APP_DIR }} | |
| run: npm run build | |
| - name: Prepare Node build folder | |
| working-directory: ${{ env.APP_DIR }} | |
| run: | | |
| mkdir -p build | |
| if [ -d dist ]; then mv dist/* build/; fi | |
| - name: Upload Node build artifact | |
| uses: actions/upload-artifact@v6 | |
| if: | |
| github.repository_owner == 'ni' && startsWith(github.ref, | |
| 'refs/heads/main') | |
| with: | |
| name: ${{ env.APP_NAME }}-build | |
| path: ${{ env.APP_DIR }}/build | |
| build-blazor: | |
| needs: generate-blazor-matrix | |
| if: needs.generate-blazor-matrix.outputs.is-empty != 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| app_dir: ${{ fromJSON(needs.generate-blazor-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Parse Blazor app | |
| run: | | |
| APP_DIR="examples/Web Apps/Framework Examples/${{ matrix.app_dir }}" | |
| APP_NAME="$(echo "${{ matrix.app_dir }}" | tr '/' '-')" | |
| echo "APP_DIR=$APP_DIR" >> $GITHUB_ENV | |
| echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0 | |
| - name: Restore Blazor dependencies | |
| working-directory: ${{ env.APP_DIR }} | |
| run: dotnet restore | |
| - name: Publish Blazor app | |
| working-directory: ${{ env.APP_DIR }} | |
| run: dotnet publish *.csproj -o dist | |
| # The dotnet.js fingerprint workaround is applied automatically via | |
| # the AfterTargets="Publish" MSBuild target in the .csproj. | |
| - name: Prepare Blazor build folder | |
| working-directory: ${{ env.APP_DIR }} | |
| run: | | |
| mkdir -p build | |
| mv dist/wwwroot/* build/ | |
| - name: Upload Blazor build artifact | |
| uses: actions/upload-artifact@v6 | |
| if: | |
| github.repository_owner == 'ni' && startsWith(github.ref, | |
| 'refs/heads/main') | |
| with: | |
| name: ${{ env.APP_NAME }}-build | |
| path: ${{ env.APP_DIR }}/build | |
| cache-slcli: | |
| if: | |
| github.repository_owner == 'ni' && startsWith(github.ref, | |
| 'refs/heads/main') | |
| runs-on: ubuntu-latest | |
| outputs: | |
| cache-key: slcli-homebrew | |
| steps: | |
| - name: Restore Homebrew cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: /home/linuxbrew/.linuxbrew | |
| key: brew-cache-${{ runner.os }}-slcli | |
| - name: Ensure slcli is installed | |
| run: | | |
| eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" | |
| brew tap ni-kismet/homebrew-ni | |
| if ! command -v slcli &>/dev/null; then | |
| brew install slcli | |
| fi | |
| echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH | |
| - name: Verify slcli | |
| run: slcli --version | |
| generate-combined-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Generate app matrix | |
| id: set-matrix | |
| run: | | |
| BASE_DIR="examples/Web Apps/Framework Examples" | |
| APPS=() | |
| for framework_dir in "$BASE_DIR"/*; do | |
| if [ -d "$framework_dir" ]; then | |
| FRAMEWORK="$(basename "$framework_dir")" | |
| for app_dir in "$framework_dir"/*; do | |
| if [ -d "$app_dir" ]; then | |
| APP_NAME="$(basename "$app_dir")" | |
| APPS+=("$FRAMEWORK/$APP_NAME") | |
| fi | |
| done | |
| fi | |
| done | |
| # Compact JSON (single line) | |
| if [ ${#APPS[@]} -eq 0 ]; then | |
| JSON_MATRIX="[]" | |
| else | |
| JSON_MATRIX=$(printf '%s\n' "${APPS[@]}" | jq -R . | jq -cs .) | |
| fi | |
| echo "matrix=$JSON_MATRIX" >> "$GITHUB_OUTPUT" | |
| package-deploy: | |
| if: | | |
| github.repository_owner == 'ni' && | |
| startsWith(github.ref, 'refs/heads/main') && | |
| needs.generate-combined-matrix.outputs.is-empty != 'true' | |
| needs: [build-node, build-blazor, cache-slcli, generate-combined-matrix] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| app_dir: ${{ fromJSON(needs.generate-combined-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Parse app | |
| run: | | |
| APP_DIR="examples/Web Apps/Framework Examples/${{ matrix.app_dir }}" | |
| APP_NAME="$(echo "${{ matrix.app_dir }}" | tr '/' '-')" | |
| echo "APP_DIR=$APP_DIR" >> $GITHUB_ENV | |
| echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV | |
| - name: Create build folder | |
| run: mkdir -p "${{ env.APP_DIR }}/build" | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: ${{ env.APP_NAME }}-build | |
| path: "${{ env.APP_DIR }}/build" | |
| - name: Restore Homebrew-slcli from cache | |
| uses: actions/cache@v3 | |
| with: | |
| path: /home/linuxbrew/.linuxbrew | |
| key: brew-cache-${{ runner.os }}-slcli | |
| - name: Add slcli to PATH | |
| run: echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH | |
| - name: Package into .nipkg | |
| working-directory: ${{ env.APP_DIR }} | |
| run: slcli webapp pack build/ --output "${{ env.APP_NAME }}.nipkg" | |
| - name: Upload .nipkg artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: ${{ env.APP_NAME }}.nipkg | |
| path: "${{ env.APP_DIR}}/${{ env.APP_NAME }}.nipkg" | |
| - name: Login to SystemLink | |
| run: | | |
| slcli login --profile ghActions --url "${{ vars.SL_API_URL }}" \ | |
| --api-key "${{ secrets.SL_API_KEY }}" \ | |
| --web-url "${{ vars.SL_WEBSITE_URL }}" \ | |
| --workspace "${{ vars.SL_WORKSPACE }}" | |
| - name: Deploy webapp to SystemLink | |
| working-directory: ${{ env.APP_DIR }} | |
| run: | | |
| pkg="${{ env.APP_NAME }}.nipkg" | |
| WEBAPP_NAME="${{ env.APP_NAME }}_PROD" | |
| WEBAPP_ID=$(slcli webapp list --workspace "${{ vars.SL_WORKSPACE }}" --filter "$WEBAPP_NAME" --format json | jq -r '.[0].id // empty') | |
| if [[ -z "$WEBAPP_ID" ]]; then | |
| echo " * Webapp does not exist -- publishing new" | |
| slcli webapp publish "$pkg" --name "$WEBAPP_NAME" --workspace "${{ vars.SL_WORKSPACE }}" | |
| else | |
| echo " * Webapp exists -- updating" | |
| slcli webapp publish "$pkg" --id "$WEBAPP_ID" | |
| fi | |
| echo "**Deployed $WEBAPP_NAME**" |