Update node PR pipeline to include an option to pass arbitrary enviro… #1
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: 🕵️ Node Pull Request Checks | ||
|
Check failure on line 1 in .github/workflows/node-pr.yml
|
||
| on: | ||
| workflow_call: | ||
| secrets: | ||
| NPM_TOKEN: | ||
| description: "NPM authentication token for private registries" | ||
| required: false | ||
| ENV_VARS: | ||
| description: "Additional environment variables as key=value pairs (one per line)" | ||
| required: false | ||
| inputs: | ||
| package-manager: | ||
| description: "Node package manager to use" | ||
| default: yarn | ||
| type: string | ||
| is-yarn-classic: | ||
| description: "If Yarn (pre-Berry) should be used" | ||
| default: false | ||
| type: boolean | ||
| build-command: | ||
| description: "Command to override the build command" | ||
| default: build | ||
| type: string | ||
| test-command: | ||
| description: "Command to override the test command" | ||
| default: test | ||
| type: string | ||
| lint-command: | ||
| description: "Command to override the lint command" | ||
| default: lint | ||
| type: string | ||
| format-command: | ||
| description: "Command to override the format command" | ||
| default: format | ||
| type: string | ||
| test-storybook-command: | ||
| description: "Command to override the test-storybook command" | ||
| default: test-storybook | ||
| type: string | ||
| check-types-command: | ||
| description: "Command to override the check-types command" | ||
| default: check-types | ||
| type: string | ||
| skip-build: | ||
| description: "If the build step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-test: | ||
| description: "If the test step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-lint: | ||
| description: "If the lint step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-format: | ||
| description: "If the format step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-test-storybook: | ||
| description: "If the test-storybook step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-check-types: | ||
| description: "If the check-types step should skipped" | ||
| default: false | ||
| type: boolean | ||
| skip-cache: | ||
| description: "If the cache should be skipped when installing dependencies" | ||
| default: false | ||
| type: boolean | ||
| pre-install-commands: | ||
| description: "Commands to run before dependency installation (e.g., configure registries, auth tokens)" | ||
| default: "" | ||
| type: string | ||
| debug: | ||
| description: "If debug flags should be set" | ||
| default: false | ||
| type: boolean | ||
| jobs: | ||
| install: | ||
| name: 🧶 Install | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| package-manager-cache: false | ||
| node-version-file: .nvmrc | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| node-version-file: .nvmrc | ||
| - name: Run pre-install commands | ||
| if: inputs.pre-install-commands != '' | ||
| env: | ||
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
| run: | | ||
| # Execute pre-install commands line by line | ||
| echo "${{ inputs.pre-install-commands }}" | while IFS= read -r cmd; do | ||
| if [ -n "$cmd" ]; then | ||
| echo "Running: $cmd" | ||
| eval "$cmd" | ||
| fi | ||
| done | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Install dependencies | ||
| run: | | ||
| debug=${{ inputs.debug && '--verbose' || '' }} | ||
| if [ "${{ inputs.package-manager }}" = "yarn" ]; then | ||
| lock_dependencies=${{ inputs.is-yarn-classic && '--frozen-lockfile' || '--immutable' }} | ||
| skip_cache=${{ inputs.skip-cache && '--force' || '' }} | ||
| yarn config get nodeLinker | ||
| yarn install $lock_dependencies $skip_cache $debug | ||
| else | ||
| npm ci $debug | ||
| fi | ||
| # Use tar to store cache so file permissions are maintained (https://github.com/actions/upload-artifact/issues/38) | ||
| - name: Archive node_modules with tar | ||
| run: tar -czf node_modules.tar.gz -C . node_modules/ | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| path: node_modules.tar.gz | ||
| check-commands: | ||
| name: 📝 Check Commands | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| has-build: ${{ steps.check.outputs.has-build }} | ||
| has-test: ${{ steps.check.outputs.has-test }} | ||
| has-lint: ${{ steps.check.outputs.has-lint }} | ||
| has-format: ${{ steps.check.outputs.has-format }} | ||
| has-test-storybook: ${{ steps.check.outputs.has-test-storybook }} | ||
| has-check-types: ${{ steps.check.outputs.has-check-types }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - id: check | ||
| run: | | ||
| scripts=$(jq -r '.scripts | keys[]' package.json) | ||
| check_command() { | ||
| command_name="$1" | ||
| output_name="$2" | ||
| if echo "$scripts" | grep -q "^$command_name$"; then | ||
| echo "$command_name script found" | ||
| echo "has-$output_name=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "$command_name script not found" | ||
| echo "has-$output_name=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| } | ||
| check_command "${{ inputs.build-command }}" "build" | ||
| check_command "${{ inputs.test-command }}" "test" | ||
| check_command "${{ inputs.lint-command }}" "lint" | ||
| check_command "${{ inputs.format-command }}" "format" | ||
| check_command "${{ inputs.test-storybook-command }}" "test-storybook" | ||
| check_command "${{ inputs.check-types-command }}" "check-types" | ||
| build: | ||
| name: 🏗️ Build | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-build == false && needs.check-commands.outputs.has-build == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Build | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.build-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| test: | ||
| name: 🧪 Test | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-test == false && needs.check-commands.outputs.has-test == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Test | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.test-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| lint: | ||
| name: 🛞 Lint | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-lint == false && needs.check-commands.outputs.has-lint == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Lint | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.lint-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| format: | ||
| name: 🖌️ Format | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-format == false && needs.check-commands.outputs.has-format == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Format | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.format-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| test-storybook: | ||
| name: 📖 Test Storybook | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-test-storybook == false && needs.check-commands.outputs.has-test-storybook == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Install Playwright | ||
| run: npx playwright install | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Test Storybook | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.test-storybook-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| check-types: | ||
| name: 🔍 Check Types | ||
| needs: [install, check-commands] | ||
| if: inputs.skip-check-types == false && needs.check-commands.outputs.has-check-types == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Fetch Origin | ||
| run: git fetch origin | ||
| - name: Install Node.js | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| package-manager-cache: false | ||
| - name: Enable Corepack | ||
| run: | | ||
| # Enable corepack if packageManager is specified in package.json | ||
| if [ -f package.json ] && jq -e '.packageManager' package.json > /dev/null 2>&1; then | ||
| echo "packageManager field detected in package.json, enabling corepack" | ||
| corepack enable | ||
| fi | ||
| - name: Configure Dependency Cache | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| cache: ${{ inputs.package-manager }} | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: node_modules | ||
| - name: Extract node_modules with tar | ||
| run: tar -xvzf node_modules.tar.gz -C . | ||
| - name: Setup additional environment variables | ||
| if: secrets.ENV_VARS != '' | ||
| run: | | ||
| # Parse and set additional environment variables | ||
| echo "${{ secrets.ENV_VARS }}" | while IFS= read -r line; do | ||
| if [ -n "$line" ] && [[ "$line" == *"="* ]]; then | ||
| echo "Setting environment variable: ${line%%=*}" | ||
| echo "$line" >> $GITHUB_ENV | ||
| fi | ||
| done | ||
| - name: Check Types | ||
| run: ${{ inputs.package-manager }} run ${{ inputs.check-types-command }} ${{ inputs.debug && '--verbose' || '' }} | ||
| cleanup: | ||
| name: 🧹 Cleanup | ||
| runs-on: ubuntu-latest | ||
| needs: [install, build, test, lint, format, test-storybook, check-types] | ||
| if: always() # Run this step regardless of success of other steps | ||
| permissions: | ||
| actions: write | ||
| steps: | ||
| - name: Delete 'node_modules' artifact from this run | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| run_id: process.env.GITHUB_RUN_ID, | ||
| }); | ||
| const artifact = artifacts.data.artifacts.find(a => a.name === 'node_modules'); | ||
| if (!artifact) { | ||
| core.info("No 'node_modules' artifact found for this run."); | ||
| } else { | ||
| await github.rest.actions.deleteArtifact({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| artifact_id: artifact.id | ||
| }); | ||
| core.info(`Deleted artifact 'node_modules' with ID ${artifact.id}`); | ||
| } | ||