feat: Added React Demo webApp and deployment workflow #11
Workflow file for this run
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 Applications/Framework Examples/**" | |
| - ".github/workflows/webapp-deploy.yml" | |
| push: | |
| branches: | |
| - "**" | |
| paths: | |
| - "examples/Web Applications/Framework Examples/**" | |
| - ".github/workflows/webapp-deploy.yml" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| generate-matrix: # find all of the web app project folders | |
| 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 Applications/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) | |
| JSON_MATRIX=$(printf '%s\n' "${APPS[@]}" | jq -R . | jq -cs .) | |
| echo "matrix=$JSON_MATRIX" >> "$GITHUB_OUTPUT" | |
| cache-package-managers: #setup package managers and cache ahead of matrix of builds (each build will have shorter setup time) | |
| runs-on: ubuntu-latest | |
| env: | |
| NODE_VERSION: "24.x" | |
| DOTNET_VERSION: "10.0" | |
| steps: | |
| - name: Set Cache for npm (from node) | |
| if: env.FRAMEWORK != 'Blazor' | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.npm | |
| key: npm-cache-${{ env.NODE_VERSION }}-${{ runner.os }} | |
| - name: Setup Node.js (npm on cache miss) | |
| if: env.FRAMEWORK != 'Blazor' | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Cache/Restore .NET SDK | |
| if: env.FRAMEWORK == 'Blazor' | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.dotnet | |
| key: dotnet-cache-${{ env.DOTNET_VERSION }}-${{ runner.os }} | |
| - name: Setup .NET SDK (on cache miss) | |
| if: env.FRAMEWORK == 'Blazor' | |
| uses: actions/setup-dotnet@v3 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| build: | |
| needs: [generate-matrix, cache-package-managers] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| frame_app_dir_path: | |
| ${{ fromJSON(needs.generate-matrix.outputs.matrix) }} | |
| env: | |
| NODE_VERSION: "24.x" | |
| DOTNET_VERSION: "10.0" | |
| steps: | |
| - name: Parse framework and app name | |
| run: | | |
| APP_DIR="examples/Web Applications/Framework Examples/${{ matrix.frame_app_dir_path }}" | |
| FRAMEWORK="$(basename "$(dirname "$APP_DIR")")" | |
| APP_NAME="$(basename "$APP_DIR")" | |
| echo "APP_DIR=$APP_DIR" >> $GITHUB_ENV | |
| echo "FRAMEWORK=$FRAMEWORK" >> $GITHUB_ENV | |
| echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV | |
| echo "Framework: $FRAMEWORK" | |
| echo "App Name: $APP_NAME" | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Restore npm from cache | |
| if: env.FRAMEWORK != 'Blazor' | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.npm | |
| key: npm-cache-${{ env.NODE_VERSION }}-${{ runner.os }} | |
| - name: Restore .NET SDK from cache | |
| if: env.FRAMEWORK == 'Blazor' | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.dotnet | |
| key: dotnet-cache-${{ env.DOTNET_VERSION }}-${{ runner.os }} | |
| - name: Restore .NET dependencies | |
| if: ${{ env.FRAMEWORK == 'Blazor' }} | |
| working-directory: ${{ env.APP_DIR }} | |
| run: dotnet restore | |
| - name: Install Node dependencies | |
| if: ${{ env.FRAMEWORK != 'Blazor' }} | |
| working-directory: ${{ env.APP_DIR }} | |
| run: npm ci | |
| - name: Lint (JS/TS only) | |
| if: ${{ env.FRAMEWORK != 'Blazor' }} | |
| working-directory: ${{ env.APP_DIR }} | |
| run: npm run lint | |
| - name: Build app (direct to ./build) | |
| working-directory: ${{ env.APP_DIR }} | |
| run: | | |
| set -e | |
| rm -rf build | |
| if [ "${{ env.FRAMEWORK }}" = "Blazor" ]; then | |
| PROJECT_FILE=$(find . -maxdepth 1 -name "*.csproj" | head -n 1) | |
| dotnet publish "$PROJECT_FILE" -c Release -o build | |
| else | |
| npm run build | |
| if [ -d dist ]; then | |
| rm -rf build | |
| mv dist build | |
| elif [ -d build ]; then | |
| echo "Build output already in build folder" | |
| else | |
| echo "Error: No build output found!" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Upload 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: #cache slcli so deploy runners run faster | |
| if: | |
| github.repository_owner == 'ni' && startsWith(github.ref, | |
| 'refs/heads/main') | |
| runs-on: ubuntu-latest | |
| outputs: | |
| cache-key: slcli-homebrew | |
| steps: | |
| - name: Restore Cache of Homebrew (including the slcli bin) | |
| uses: actions/cache@v3 | |
| with: | |
| path: /home/linuxbrew/.linuxbrew | |
| key: brew-cache-${{ runner.os }}-slcli | |
| - name: (on cache miss) Setup Homebrew + Install slcli | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" | |
| brew tap ni-kismet/homebrew-ni | |
| brew install slcli || true | |
| echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH | |
| - name: Verify slcli | |
| run: slcli --version | |
| package-deploy: | |
| needs: [build, generate-matrix, cache-slcli] | |
| if: | |
| github.repository_owner == 'ni' && startsWith(github.ref, | |
| 'refs/heads/main') | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| app_dir: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }} | |
| steps: | |
| - name: Parse framework and app name | |
| run: | | |
| APP_DIR="examples/Web Applications/Framework Examples/${{ matrix.app_dir }}" | |
| FRAMEWORK="$(basename "$(dirname "$APP_DIR")")" | |
| APP_NAME="$(basename "$APP_DIR")" | |
| echo "APP_DIR=$APP_DIR" >> $GITHUB_ENV | |
| echo "FRAMEWORK=$FRAMEWORK" >> $GITHUB_ENV | |
| echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV | |
| - name: Create app 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 to GitHub | |
| 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 "${{ secrets.SL_API_URL }}" \ | |
| --api-key "${{ secrets.SL_API_KEY }}" \ | |
| --web-url "${{ secrets.SL_WEBSITE_URL }}" \ | |
| --workspace "${{ secrets.SL_WORKSPACE }}" | |
| - name: Deploy webapp to SystemLink | |
| working-directory: ${{ env.APP_DIR }} | |
| run: | | |
| pkg="${{ env.APP_NAME }}.nipkg" | |
| WEBAPP_NAME="${{ env.APP_NAME }}_PROD" | |
| echo "**Deploying $pkg as $WEBAPP_NAME**" | |
| WEBAPP_ID=$(slcli webapp list --workspace "${{ secrets.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 "${{ secrets.SL_WORKSPACE }}" | |
| else | |
| echo " * Webapp exists -- updating" | |
| slcli webapp publish "$pkg" --id "$WEBAPP_ID" | |
| fi | |
| echo "**Deployed $WEBAPP_NAME**" |