From 876f19223bfaee319d23fd86018237dc39bb1e9b Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Wed, 18 Mar 2026 15:49:45 +1030 Subject: [PATCH 1/8] DO-1802: Add Yamllinting, actionlinting and zizmor static analysis to our github workflows --- .github/actionlint.yml | 6 ++++++ .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ .yamllint.yml | 15 +++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 .github/actionlint.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .yamllint.yml diff --git a/.github/actionlint.yml b/.github/actionlint.yml new file mode 100644 index 0000000..e748bad --- /dev/null +++ b/.github/actionlint.yml @@ -0,0 +1,6 @@ +paths: + # CST_REPORTING_TOKEN is an org-level secret โ€” not declared in the workflow + # but valid at runtime. actionlint cannot see org-level secrets. + ".github/workflows/magento-cloud-deploy.yml": + ignore: + - 'property "cst_reporting_token" is not defined' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6c0fd61 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + pull_request: + +jobs: + checks: + name: Lint & Static Analysis + runs-on: ubuntu-latest + permissions: + security-events: write + contents: read # only needed for private or internal repos + actions: read # only needed for private or internal repos + steps: + - uses: actions/checkout@v6 + + - name: yamllint + run: yamllint . + + - name: actionlint + uses: rhysd/action-actionlint@393031adb9afb225ee52ae2ccd7a5af5525e03e8 + + - name: zizmor + uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..8391650 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,15 @@ +extends: default +rules: + document-start: disable + trailing-spaces: disable + line-length: + max: 120 + truthy: + allowed-values: ["true", "false", "on"] + indentation: + spaces: 2 + indent-sequences: true + check-multi-line-strings: false + level: warning + comments: + min-spaces-from-content: 1 From d2effa6eaac560d090b3a694dc572c3bf6dfa2c8 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Wed, 18 Mar 2026 15:57:32 +1030 Subject: [PATCH 2/8] DO-1802: use the correct action for actionlint --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c0fd61..398dfdf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: run: yamllint . - name: actionlint - uses: rhysd/action-actionlint@393031adb9afb225ee52ae2ccd7a5af5525e03e8 + uses: raven-actions/actionlint@205b530c5d9fa8f44ae9ed59f341a0db994aa6f8 # v2.1.2 - name: zizmor - uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 + uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 From 4fdf2e13d5064378031f76fc9829311d26da9dc6 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Wed, 18 Mar 2026 15:58:33 +1030 Subject: [PATCH 3/8] Fix linting issues --- .github/actions/command-exists/action.yml | 5 +- .github/workflows/aws-cdk.yml | 10 +++- .github/workflows/changeset-check.yml | 7 ++- .github/workflows/changeset-release.yml | 12 +++-- .github/workflows/gadget-deploy.yml | 13 +++-- .github/workflows/magento-cloud-deploy.yml | 24 ++++++--- .github/workflows/node-pr.yml | 21 ++++++-- .../workflows/nx-serverless-deployment.yml | 8 ++- .github/workflows/php-quality-checks.yml | 49 +++++++++++++++---- .github/workflows/pwa-deployment.yml | 16 ++++-- .github/workflows/s3-deploy.yml | 8 +-- .github/workflows/shopify-deploy.yml | 8 +-- .../workflows/static-hosting-deployment.yml | 1 - 13 files changed, 130 insertions(+), 52 deletions(-) diff --git a/.github/actions/command-exists/action.yml b/.github/actions/command-exists/action.yml index fe45833..9e23606 100644 --- a/.github/actions/command-exists/action.yml +++ b/.github/actions/command-exists/action.yml @@ -58,7 +58,8 @@ runs: if [ -f "pnpm-workspace.yaml" ]; then # Extract package paths from YAML list items, stripping optional quotes # Matches: " - packages/*", " - 'apps/*'", ' - "libs/*"' -> packages/*, apps/*, libs/* - pnpm_packages=$(grep -E '^\s*-\s+' pnpm-workspace.yaml | sed "s/.*-\s*['\"]\\{0,1\\}\([^'\"]*\\)['\"]\\{0,1\\}/\1/" 2>/dev/null) + pnpm_packages=$(grep -E '^\s*-\s+' pnpm-workspace.yaml \ + | sed "s/.*-\s*['\"]\\{0,1\\}\([^'\"]*\\)['\"]\\{0,1\\}/\1/" 2>/dev/null) for pattern in $pnpm_packages; do for pkg_dir in $pattern; do if [ -f "$pkg_dir/package.json" ]; then @@ -86,4 +87,4 @@ runs: fi fi - echo "exists=false" >> $GITHUB_OUTPUT \ No newline at end of file + echo "exists=false" >> $GITHUB_OUTPUT diff --git a/.github/workflows/aws-cdk.yml b/.github/workflows/aws-cdk.yml index 688493c..9de05a8 100644 --- a/.github/workflows/aws-cdk.yml +++ b/.github/workflows/aws-cdk.yml @@ -177,10 +177,14 @@ jobs: uses: actions/setup-node@v6 with: node-version: ${{ steps.node-version.outputs.version }} + # yamllint disable rule:line-length cache: ${{ steps.detect-package-manager.outputs.manager == 'yarn-berry' && 'yarn' || (steps.detect-package-manager.outputs.manager == 'yarn-classic' && 'yarn' || steps.detect-package-manager.outputs.manager) }} + # yamllint enable rule:line-length - name: Install safe-chain - run: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + run: | + SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh" + curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci - name: Install dependencies run: | @@ -291,7 +295,9 @@ jobs: fi # Validate that at least one of synth, diff or deploy is true - if [ "${{ inputs.synth }}" != "true" ] && [ "${{ inputs.diff }}" != "true" ] && [ "${{ inputs.deploy }}" != "true" ]; then + if [ "${{ inputs.synth }}" != "true" ] && \ + [ "${{ inputs.diff }}" != "true" ] && \ + [ "${{ inputs.deploy }}" != "true" ]; then echo "โŒ Error: At least one of synth, diff, or deploy must be true" exit 1 fi diff --git a/.github/workflows/changeset-check.yml b/.github/workflows/changeset-check.yml index d33f113..9cadace 100644 --- a/.github/workflows/changeset-check.yml +++ b/.github/workflows/changeset-check.yml @@ -174,7 +174,9 @@ jobs: echo "needs_changeset=true" >> $GITHUB_OUTPUT echo "Affected packages found but no changesets detected" else - PACKAGES_WITH_CHANGESETS=$(echo "$CHANGESET_STATUS" | jq -r '.releases[] | select(.changesets | length > 0) | .name' 2>/dev/null || echo "") + JQ_FILTER='.releases[] | select(.changesets | length > 0) | .name' + PACKAGES_WITH_CHANGESETS=$(echo "$CHANGESET_STATUS" \ + | jq -r "$JQ_FILTER" 2>/dev/null || echo "") ALL_COVERED=true for pkg in $PUBLISHABLE_AFFECTED; do @@ -253,7 +255,8 @@ jobs: `${changesetCmd} --empty`, '```', '', - `**Tip:** When running \`${changesetCmd}\`, select only the packages listed above that you actually changed the public API of.`, + `**Tip:** When running \`${changesetCmd}\`, select only the packages ` + + `listed above that you actually changed the public API of.`, '', '' ].join('\n'); diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index ad4fe36..46891d5 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -16,7 +16,9 @@ on: default: "" type: string pre-publish-commands: - description: "Commands to run after install but before the changesets action (e.g., build, generate-types, run tests)" + description: >- + Commands to run after install but before the changesets action + (e.g., build, generate-types, run tests) default: "" type: string publish-command: @@ -40,7 +42,9 @@ on: default: true type: boolean npm-registry-url: - description: "npm registry URL for setup-node (used for OIDC/token-based npm publishing). Leave empty if not needed." + description: >- + npm registry URL for setup-node (used for OIDC/token-based npm publishing). + Leave empty if not needed. default: "" type: string post-publish-commands: @@ -56,7 +60,9 @@ on: description: "NPM authentication token for private registries (used during install and publishing)" required: false GITHUB_PAT: - description: "GitHub PAT if the default GITHUB_TOKEN is insufficient (e.g., for triggering other workflows from changeset commits)" + description: >- + GitHub PAT if the default GITHUB_TOKEN is insufficient + (e.g., for triggering other workflows from changeset commits) required: false jobs: diff --git a/.github/workflows/gadget-deploy.yml b/.github/workflows/gadget-deploy.yml index bedf680..716987a 100644 --- a/.github/workflows/gadget-deploy.yml +++ b/.github/workflows/gadget-deploy.yml @@ -1,4 +1,3 @@ - name: ๐Ÿค– Gadget Deploy on: workflow_call: @@ -40,7 +39,6 @@ on: description: "Gadget Test API key for running tests" required: false - jobs: push: name: ๐Ÿซธ Push to Gadget @@ -48,7 +46,7 @@ jobs: env: GGT_TOKEN: ${{ secrets.gadget-api-token }} outputs: - push-environment-status: ${{ steps.push-environment.outcome }} + push-environment-status: ${{ steps.push-environment.outcome }} if: inputs.push-staging == true steps: - uses: actions/checkout@v6 @@ -92,7 +90,9 @@ jobs: cache-dependency-path: ${{ inputs.working-directory }}/yarn.lock - name: Install safe-chain - run: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + run: | + SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh" + curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci - name: Install dependencies working-directory: ${{ inputs.working-directory }} @@ -122,4 +122,7 @@ jobs: - name: Deploy (promote) to Production environment in Gadget working-directory: ${{ inputs.working-directory }} run: | - ggt deploy --app=${{ inputs.app-name }} --env=${{ inputs.environment-name }} --force --allow-unknown-directory --allow-problems \ No newline at end of file + ggt deploy \ + --app=${{ inputs.app-name }} \ + --env=${{ inputs.environment-name }} \ + --force --allow-unknown-directory --allow-problems diff --git a/.github/workflows/magento-cloud-deploy.yml b/.github/workflows/magento-cloud-deploy.yml index 9c42a10..5c77099 100644 --- a/.github/workflows/magento-cloud-deploy.yml +++ b/.github/workflows/magento-cloud-deploy.yml @@ -82,7 +82,9 @@ jobs: exit 1 fi - if [ "${{ inputs.environment }}" != "integration" ] && [ "${{ inputs.environment }}" != "staging" ] && [ "${{ inputs.environment }}" != "production" ]; then + if [ "${{ inputs.environment }}" != "integration" ] && \ + [ "${{ inputs.environment }}" != "staging" ] && \ + [ "${{ inputs.environment }}" != "production" ]; then echo "โŒ Error: environment must be one of: integration, staging, production" exit 1 fi @@ -167,11 +169,17 @@ jobs: echo "๐Ÿ“‹ Retrieving deployment information..." # Get environment URL - URL=$(magento-cloud url --environment "${{ inputs.environment }}" --project "${{ inputs.magento-cloud-project-id }}" --pipe | tr -d '[:space:]') + URL=$(magento-cloud url \ + --environment "${{ inputs.environment }}" \ + --project "${{ inputs.magento-cloud-project-id }}" \ + --pipe | tr -d '[:space:]') echo "url=$URL" >> "$GITHUB_OUTPUT" # Get deployment ID - DEPLOYMENT_ID=$(magento-cloud activity:list --environment "${{ inputs.environment }}" --type push --limit 1 --format csv --columns id --no-header | head -1) + DEPLOYMENT_ID=$(magento-cloud activity:list \ + --environment "${{ inputs.environment }}" \ + --type push --limit 1 --format csv \ + --columns id --no-header | head -1) echo "id=$DEPLOYMENT_ID" >> "$GITHUB_OUTPUT" if [ "${{ inputs.debug }}" = "true" ]; then @@ -182,6 +190,8 @@ jobs: - name: Generate deployment summary run: | + DEPLOY_URL="${{ steps.deploy-info.outputs.url }}" + echo "## ๐Ÿ›๏ธ Magento Cloud Deployment Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY @@ -189,7 +199,7 @@ jobs: echo "| **Project ID** | ${{ inputs.magento-cloud-project-id }} |" >> $GITHUB_STEP_SUMMARY echo "| **Environment** | ${{ inputs.environment }} |" >> $GITHUB_STEP_SUMMARY echo "| **Deployment ID** | ${{ steps.deploy-info.outputs.id }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Site URL** | [${{ steps.deploy-info.outputs.url }}](${{ steps.deploy-info.outputs.url }}) |" >> $GITHUB_STEP_SUMMARY + echo "| **Site URL** | [$DEPLOY_URL]($DEPLOY_URL) |" >> $GITHUB_STEP_SUMMARY echo "| **Git Commit** | ${{ github.sha }} |" >> $GITHUB_STEP_SUMMARY echo "| **Deployed By** | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY @@ -198,17 +208,17 @@ jobs: "production") echo "### ๐ŸŒ Production Deployment" >> $GITHUB_STEP_SUMMARY echo "Your Magento store is now live at:" >> $GITHUB_STEP_SUMMARY - echo "**[${{ steps.deploy-info.outputs.url }}](${{ steps.deploy-info.outputs.url }})**" >> $GITHUB_STEP_SUMMARY + echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY ;; "staging") echo "### ๐Ÿš€ Staging Environment" >> $GITHUB_STEP_SUMMARY echo "Staging environment updated successfully:" >> $GITHUB_STEP_SUMMARY - echo "**[${{ steps.deploy-info.outputs.url }}](${{ steps.deploy-info.outputs.url }})**" >> $GITHUB_STEP_SUMMARY + echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY ;; *) echo "### ๐Ÿ”ง Integration Environment" >> $GITHUB_STEP_SUMMARY echo "Integration environment deployed for testing:" >> $GITHUB_STEP_SUMMARY - echo "**[${{ steps.deploy-info.outputs.url }}](${{ steps.deploy-info.outputs.url }})**" >> $GITHUB_STEP_SUMMARY + echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY ;; esac diff --git a/.github/workflows/node-pr.yml b/.github/workflows/node-pr.yml index 2427348..c9232c4 100644 --- a/.github/workflows/node-pr.yml +++ b/.github/workflows/node-pr.yml @@ -87,7 +87,9 @@ on: default: 1 type: number pre-test-command: - description: "A script to run before the test checks (e.g., generate:types for code generation). Runs as: run " + description: >- + A script to run before the test checks (e.g., generate:types for code generation). + Runs as: run default: "" type: string node-options: @@ -123,7 +125,9 @@ jobs: cache: ${{ inputs.package-manager }} node-version-file: .nvmrc - name: Install safe-chain - run: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + run: | + SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh" + curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci - name: Setup additional environment variables if: inputs.has-env-vars run: | @@ -278,7 +282,12 @@ jobs: test: name: ๐Ÿงช Pull Request Checks needs: [install] - if: inputs.skip-test == false || inputs.skip-lint == false || inputs.skip-format == false || inputs.skip-test-storybook == false || inputs.skip-check-types == false + if: >- + inputs.skip-test == false || + inputs.skip-lint == false || + inputs.skip-format == false || + inputs.skip-test-storybook == false || + inputs.skip-check-types == false runs-on: ubuntu-latest env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} @@ -391,7 +400,8 @@ jobs: if [ "${{ inputs.skip-format }}" != "true" ] && [ "${{ steps.check-format.outputs.exists }}" == "true" ]; then commands+=("${{ inputs.format-command }}") fi - if [ "${{ inputs.skip-test-storybook }}" != "true" ] && [ "${{ steps.check-test-storybook.outputs.exists }}" == "true" ]; then + if [ "${{ inputs.skip-test-storybook }}" != "true" ] && \ + [ "${{ steps.check-test-storybook.outputs.exists }}" == "true" ]; then # Ensure playwright dependencies are installed before story blok test execution begins if [ "${{ inputs.package-manager }}" = "yarn" ]; then yarn playwright install --with-deps @@ -400,7 +410,8 @@ jobs: fi commands+=("${{ inputs.test-storybook-command }}") fi - if [ "${{ inputs.skip-check-types }}" != "true" ] && [ "${{ steps.check-check-types.outputs.exists }}" == "true" ]; then + if [ "${{ inputs.skip-check-types }}" != "true" ] && \ + [ "${{ steps.check-check-types.outputs.exists }}" == "true" ]; then commands+=("${{ inputs.check-types-command }}") fi # Convert to JSON array diff --git a/.github/workflows/nx-serverless-deployment.yml b/.github/workflows/nx-serverless-deployment.yml index c3446a9..07654f6 100644 --- a/.github/workflows/nx-serverless-deployment.yml +++ b/.github/workflows/nx-serverless-deployment.yml @@ -92,7 +92,9 @@ jobs: cache: ${{ inputs.package-manager }} - name: Install safe-chain - run: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + run: | + SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh" + curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci - name: Install dependencies run: | @@ -151,7 +153,9 @@ jobs: yq ".provider.cfnRole = \"${0}\"" "$1" | sed "s/!!merge < "$1.tmp" && mv "$1.tmp" "$1" ' "$CFN_ROLE" {} \; else - yq ".provider.cfnRole = \"$CFN_ROLE\"" serverless.yml | sed "s/!!merge < serverless.yml.tmp && mv serverless.yml.tmp serverless.yml + yq ".provider.cfnRole = \"$CFN_ROLE\"" serverless.yml \ + | sed "s/!!merge < serverless.yml.tmp \ + && mv serverless.yml.tmp serverless.yml fi env: AWS_ACCESS_KEY_ID: ${{ vars.AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/php-quality-checks.yml b/.github/workflows/php-quality-checks.yml index c0badcb..e5aa921 100644 --- a/.github/workflows/php-quality-checks.yml +++ b/.github/workflows/php-quality-checks.yml @@ -17,7 +17,9 @@ on: description: "PHP Extensions to use redis, exif, etc" type: string required: false - default: "bcmath bz2 calendar exif gd gettext intl mysqli opcache pdo_mysql redis soap sockets sodium sysvmsg sysvsem sysvshm xsl zip pcntl" + default: >- + bcmath bz2 calendar exif gd gettext intl mysqli opcache pdo_mysql + redis soap sockets sodium sysvmsg sysvsem sysvshm xsl zip pcntl skip-composer-validate: description: "Skip Validation of the composer.json" @@ -129,7 +131,9 @@ on: default: "2" opensearch-image: - description: "OpenSearch Docker image name, combined with opensearch-version as the tag (e.g., aligent/bitbucket-opensearch)" + description: >- + OpenSearch Docker image name, combined with opensearch-version as the tag + (e.g., aligent/bitbucket-opensearch) type: string required: false default: "opensearchproject/opensearch" @@ -599,7 +603,10 @@ jobs: pushd dev/tests/unit # Build PHPUnit command with coverage - cmd='php -d memory_limit=${{ inputs.memory-limit }} -d xdebug.mode=coverage $phpunit_cmd -c ./phpunit.xml --testsuite="Unit Tests" --log-junit ./test-results/report.xml' + cmd='php -d memory_limit=${{ inputs.memory-limit }}' + cmd+=' -d xdebug.mode=coverage $phpunit_cmd' + cmd+=' -c ./phpunit.xml --testsuite="Unit Tests"' + cmd+=' --log-junit ./test-results/report.xml' cmd="$cmd --coverage-text --coverage-clover=coverage.xml" # Add debug flags if enabled @@ -677,24 +684,32 @@ jobs: options: --health-cmd="mariadb-admin ping" --health-interval=10s --health-timeout=5s --health-retries=5 search: + # yamllint disable rule:line-length image: ${{ inputs.opensearch-image }}${{ inputs.opensearch-version && format(':{0}', inputs.opensearch-version) || '' }} + # yamllint enable rule:line-length env: discovery.type: single-node OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m DISABLE_SECURITY_PLUGIN: true ports: - 9200:9200 - options: --health-cmd="curl -f http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="curl -f http://localhost:9200/_cluster/health" + --health-interval=10s --health-timeout=5s --health-retries=5 rabbitmq: + # yamllint disable rule:line-length image: ${{ inputs.rabbitmq-image }}${{ inputs.rabbitmq-version && format(':{0}', inputs.rabbitmq-version) || '' }} + # yamllint enable rule:line-length env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest ports: - 5672:5672 - 15672:15672 - options: --health-cmd="rabbitmq-diagnostics -q ping" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="rabbitmq-diagnostics -q ping" + --health-interval=10s --health-timeout=5s --health-retries=5 steps: - uses: actions/checkout@v6 @@ -787,24 +802,32 @@ jobs: options: --health-cmd="mariadb-admin ping" --health-interval=10s --health-timeout=5s --health-retries=5 search: + # yamllint disable rule:line-length image: ${{ inputs.opensearch-image }}${{ inputs.opensearch-version && format(':{0}', inputs.opensearch-version) || '' }} + # yamllint enable rule:line-length env: discovery.type: single-node OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m DISABLE_SECURITY_PLUGIN: true ports: - 9200:9200 - options: --health-cmd="curl -f http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="curl -f http://localhost:9200/_cluster/health" + --health-interval=10s --health-timeout=5s --health-retries=5 rabbitmq: + # yamllint disable rule:line-length image: ${{ inputs.rabbitmq-image }}${{ inputs.rabbitmq-version && format(':{0}', inputs.rabbitmq-version) || '' }} + # yamllint enable rule:line-length env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest ports: - 5672:5672 - 15672:15672 - options: --health-cmd="rabbitmq-diagnostics -q ping" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="rabbitmq-diagnostics -q ping" + --health-interval=10s --health-timeout=5s --health-retries=5 steps: - uses: actions/checkout@v6 @@ -918,24 +941,32 @@ jobs: options: --health-cmd="mariadb-admin ping" --health-interval=10s --health-timeout=5s --health-retries=5 search: + # yamllint disable rule:line-length image: ${{ inputs.opensearch-image }}${{ inputs.opensearch-version && format(':{0}', inputs.opensearch-version) || '' }} + # yamllint enable rule:line-length env: discovery.type: single-node OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m DISABLE_SECURITY_PLUGIN: true ports: - 9200:9200 - options: --health-cmd="curl -f http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="curl -f http://localhost:9200/_cluster/health" + --health-interval=10s --health-timeout=5s --health-retries=5 rabbitmq: + # yamllint disable rule:line-length image: ${{ inputs.rabbitmq-image }}${{ inputs.rabbitmq-version && format(':{0}', inputs.rabbitmq-version) || '' }} + # yamllint enable rule:line-length env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest ports: - 5672:5672 - 15672:15672 - options: --health-cmd="rabbitmq-diagnostics -q ping" --health-interval=10s --health-timeout=5s --health-retries=5 + options: >- + --health-cmd="rabbitmq-diagnostics -q ping" + --health-interval=10s --health-timeout=5s --health-retries=5 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/pwa-deployment.yml b/.github/workflows/pwa-deployment.yml index d3af775..fd5f91f 100644 --- a/.github/workflows/pwa-deployment.yml +++ b/.github/workflows/pwa-deployment.yml @@ -168,7 +168,8 @@ jobs: if [ -n "${{ inputs.preview-base-url }}" ]; then echo "deployment-url=${{ inputs.preview-base-url }}/${PREFIX}/" >> $GITHUB_OUTPUT else - echo "deployment-url=https://${{ inputs.s3-bucket }}.s3.amazonaws.com/${PREFIX}/index.html" >> $GITHUB_OUTPUT + DEPLOY_URL="https://${{ inputs.s3-bucket }}.s3.amazonaws.com/${PREFIX}/index.html" + echo "deployment-url=$DEPLOY_URL" >> $GITHUB_OUTPUT fi else # Production/staging deployment to root @@ -298,7 +299,9 @@ jobs: echo "๐Ÿš€ Deploying static assets..." # Deploy static assets with immutable cache headers (exclude HTML and service-worker.js) - aws s3 sync "${{ inputs.build-directory }}" "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ + aws s3 sync \ + "${{ inputs.build-directory }}" \ + "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ --exclude "*.html" \ --exclude "service-worker.js" \ --cache-control "${{ needs.prepare.outputs.cache-control-static }}" \ @@ -310,7 +313,9 @@ jobs: echo "๐Ÿ“„ Deploying HTML files and service worker..." # Deploy HTML and service-worker.js with revalidation cache headers - aws s3 sync "${{ inputs.build-directory }}" "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ + aws s3 sync \ + "${{ inputs.build-directory }}" \ + "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ --exclude "*" \ --include "*.html" \ --include "service-worker.js" \ @@ -374,12 +379,13 @@ jobs: echo "- **Build Directory**: ${{ inputs.build-directory }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY + DEPLOY_URL="${{ needs.prepare.outputs.deployment-url }}" if [ "${{ inputs.preview-mode }}" = "true" ]; then echo "### ๐Ÿ” Preview Environment" >> $GITHUB_STEP_SUMMARY echo "This is a preview deployment. The application is available at:" >> $GITHUB_STEP_SUMMARY - echo "**[${{ needs.prepare.outputs.deployment-url }}](${{ needs.prepare.outputs.deployment-url }})**" >> $GITHUB_STEP_SUMMARY + echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY else echo "### ๐ŸŒ Deployment" >> $GITHUB_STEP_SUMMARY echo "Application deployed to ${{ inputs.environment }} environment:" >> $GITHUB_STEP_SUMMARY - echo "**[${{ needs.prepare.outputs.deployment-url }}](${{ needs.prepare.outputs.deployment-url }})**" >> $GITHUB_STEP_SUMMARY + echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/s3-deploy.yml b/.github/workflows/s3-deploy.yml index 12fd79f..6ead1a5 100644 --- a/.github/workflows/s3-deploy.yml +++ b/.github/workflows/s3-deploy.yml @@ -21,7 +21,6 @@ on: description: "Path to deploy" type: string required: true - default: "" delete-flag: description: "Enable --delete flag" type: boolean @@ -68,14 +67,11 @@ jobs: cache_control="--cache-control \"${{inputs.cache-control}}\"" fi - command="aws s3 sync ${{inputs.local-path}} s3://${{inputs.s3-bucket}}${{inputs.s3-path}} ${cache_control} ${{inputs.extra-args}}" + command="aws s3 sync ${{inputs.local-path}}" + command="$command s3://${{inputs.s3-bucket}}${{inputs.s3-path}} ${cache_control} ${{inputs.extra-args}}" if [ "${{inputs.delete-flag}}" = "true" ]; then command="$command --delete" fi $command - - - - diff --git a/.github/workflows/shopify-deploy.yml b/.github/workflows/shopify-deploy.yml index 76c3046..99915fc 100644 --- a/.github/workflows/shopify-deploy.yml +++ b/.github/workflows/shopify-deploy.yml @@ -45,7 +45,7 @@ jobs: echo "Error: Neither 'deploy-staging' nor 'deploy-production' is selected." echo "Please select at least one deployment target." exit 1 - + - name: Checkout code uses: actions/checkout@v6 @@ -57,7 +57,9 @@ jobs: cache-dependency-path: ${{ inputs.working-directory }}/yarn.lock - name: Install safe-chain - run: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + run: | + SAFE_CHAIN_URL="https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh" + curl -fsSL "$SAFE_CHAIN_URL" | sh -s -- --ci - name: Install dependencies working-directory: ${{ inputs.working-directory }} @@ -83,4 +85,4 @@ jobs: run: yarn shopify app deploy --allow-updates env: SHOPIFY_CLI_TOKEN: ${{ secrets.shopify_cli_token }} - SHOPIFY_FLAG_PATH: ${{ inputs.working-directory }} \ No newline at end of file + SHOPIFY_FLAG_PATH: ${{ inputs.working-directory }} diff --git a/.github/workflows/static-hosting-deployment.yml b/.github/workflows/static-hosting-deployment.yml index 61f16b2..498ebf5 100644 --- a/.github/workflows/static-hosting-deployment.yml +++ b/.github/workflows/static-hosting-deployment.yml @@ -36,7 +36,6 @@ on: description: "Path to deploy" type: string required: true - default: "" DELETE_FLAG: description: "Enable __delete flag" type: string From 935c0410f81f38821275ebbae45d449bd3e61e15 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Wed, 18 Mar 2026 16:08:48 +1030 Subject: [PATCH 4/8] DO-1802: Ignore SC2086 for now --- .shellcheckrc | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .shellcheckrc diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..1833217 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,5 @@ +# SC2086: Double quote to prevent globbing and word splitting +# Suppressed globally โ€” variables in these workflows are GitHub-set paths or +# simple identifiers (package manager names, flags, env names) that cannot +# contain spaces. Re-evaluate if user-controlled path inputs are introduced. +disable=SC2086 From ca65dea24332ff1ed7e5bc12a36964c569c4398f Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Wed, 18 Mar 2026 16:10:49 +1030 Subject: [PATCH 5/8] DO-1802: Disable shellcheck for now as we cannot disable specific rules --- .github/workflows/ci.yml | 2 ++ .shellcheckrc | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 .shellcheckrc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 398dfdf..119897b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,8 @@ jobs: - name: actionlint uses: raven-actions/actionlint@205b530c5d9fa8f44ae9ed59f341a0db994aa6f8 # v2.1.2 + with: + shellcheck: false - name: zizmor uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 diff --git a/.shellcheckrc b/.shellcheckrc deleted file mode 100644 index 1833217..0000000 --- a/.shellcheckrc +++ /dev/null @@ -1,5 +0,0 @@ -# SC2086: Double quote to prevent globbing and word splitting -# Suppressed globally โ€” variables in these workflows are GitHub-set paths or -# simple identifiers (package manager names, flags, env names) that cannot -# contain spaces. Re-evaluate if user-controlled path inputs are introduced. -disable=SC2086 From 5b9c652650c76f589150e9aabd46a1a7ba4efd97 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Thu, 19 Mar 2026 09:36:49 +1030 Subject: [PATCH 6/8] Linting and zizmor fixes for all our workflows --- .github/actions/command-exists/action.yml | 8 +- .github/actions/run-checks/action.yml | 11 +- .github/dependabot.yml | 2 + .../aem-sync-to-cloudmanager-repo.yml | 19 ++- .github/workflows/aws-cdk.yml | 146 +++++++++++------ .github/workflows/changeset-check.yml | 32 ++-- .github/workflows/changeset-release.yml | 19 ++- .github/workflows/ci.yml | 2 + .github/workflows/gadget-deploy.yml | 24 ++- .github/workflows/magento-cloud-deploy.yml | 112 ++++++++----- .github/workflows/node-pr.yml | 82 ++++++--- .../workflows/nx-serverless-deployment.yml | 15 +- .github/workflows/php-quality-checks.yml | 78 ++++++--- .github/workflows/pwa-deployment.yml | 155 ++++++++++++------ .github/workflows/s3-deploy.yml | 18 +- .github/workflows/shopify-deploy.yml | 9 +- .../workflows/static-hosting-deployment.yml | 5 + .github/workflows/update-lockfile.yml | 19 ++- 18 files changed, 518 insertions(+), 238 deletions(-) diff --git a/.github/actions/command-exists/action.yml b/.github/actions/command-exists/action.yml index 9e23606..d328f40 100644 --- a/.github/actions/command-exists/action.yml +++ b/.github/actions/command-exists/action.yml @@ -23,7 +23,7 @@ runs: - id: check-script shell: bash run: | - cmd="${{ inputs.command }}" + cmd="${INPUTS_COMMAND}" # Check root package.json scripts if jq -e --arg cmd "$cmd" '.scripts[$cmd]' package.json > /dev/null 2>&1; then @@ -73,11 +73,13 @@ runs: fi echo "exists=false" >> $GITHUB_OUTPUT + env: + INPUTS_COMMAND: ${{ inputs.command }} - id: check-nx shell: bash run: | - cmd="${{ inputs.command }}" + cmd="${INPUTS_COMMAND}" # Check Nx targets if this is an Nx workspace if [ -f "nx.json" ]; then @@ -88,3 +90,5 @@ runs: fi echo "exists=false" >> $GITHUB_OUTPUT + env: + INPUTS_COMMAND: ${{ inputs.command }} diff --git a/.github/actions/run-checks/action.yml b/.github/actions/run-checks/action.yml index eb9e760..97c2ae8 100644 --- a/.github/actions/run-checks/action.yml +++ b/.github/actions/run-checks/action.yml @@ -17,15 +17,15 @@ runs: using: composite steps: - id: add-matchers - uses: aligent/workflows/.github/actions/node-problem-matchers@main + uses: aligent/workflows/.github/actions/node-problem-matchers@main # zizmor: ignore[unpinned-uses] trusted source - id: run shell: bash run: | debug=${{ inputs.debug == 'true' && '--verbose' || '' }} - pm=${{ inputs.package-manager }} + pm=${INPUTS_PACKAGE_MANAGER} # Parse JSON array of commands - readarray -t commands < <(echo '${{ inputs.commands }}' | jq -r '.[]') + readarray -t commands < <(echo '${INPUTS_COMMANDS}' | jq -r '.[]') if [ ${#commands[@]} -gt 0 ]; then # Build the full command strings @@ -39,8 +39,11 @@ runs: else echo "No commands to run" fi + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_COMMANDS: ${{ inputs.commands }} - id: remove-matchers if: always() - uses: aligent/workflows/.github/actions/node-problem-matchers@main + uses: aligent/workflows/.github/actions/node-problem-matchers@main # zizmor: ignore[unpinned-uses] trusted source with: action: remove diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5ace460..6cc0071 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,5 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 diff --git a/.github/workflows/aem-sync-to-cloudmanager-repo.yml b/.github/workflows/aem-sync-to-cloudmanager-repo.yml index 17f479a..e00dc11 100644 --- a/.github/workflows/aem-sync-to-cloudmanager-repo.yml +++ b/.github/workflows/aem-sync-to-cloudmanager-repo.yml @@ -97,6 +97,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + with: + persist-credentials: false - name: Cache Maven packages if: ${{ !env.ACT }} # Skip when running with act locally @@ -132,6 +134,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + with: + persist-credentials: false - name: Cache Maven packages if: ${{ !env.ACT }} # Skip when running with act locally @@ -168,6 +172,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Configure Git run: | @@ -193,11 +198,11 @@ jobs: # Determine branch name if [ -n "$REMOTE_BRANCH" ]; then - BRANCH="${{ github.ref_name }}:${REMOTE_BRANCH}" - echo "๐Ÿ“‹ Pushing '${{ github.ref_name }}' to Cloud Manager branch '${REMOTE_BRANCH}'" + BRANCH="${GITHUB_REF_NAME}:${REMOTE_BRANCH}" + echo "๐Ÿ“‹ Pushing '${GITHUB_REF_NAME}' to Cloud Manager branch '${REMOTE_BRANCH}'" else - BRANCH="${{ github.ref_name }}" - echo "๐Ÿ“‹ Pushing '${{ github.ref_name }}' to Cloud Manager" + BRANCH="${GITHUB_REF_NAME}" + echo "๐Ÿ“‹ Pushing '${GITHUB_REF_NAME}' to Cloud Manager" fi # Push to Cloud Manager @@ -215,16 +220,16 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY - echo "| **Source Branch** | ${{ github.ref_name }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Source Branch** | ${GITHUB_REF_NAME} |" >> $GITHUB_STEP_SUMMARY if [ -n "$REMOTE_BRANCH" ]; then echo "| **Target Branch** | ${REMOTE_BRANCH} |" >> $GITHUB_STEP_SUMMARY else - echo "| **Target Branch** | ${{ github.ref_name }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Target Branch** | ${GITHUB_REF_NAME} |" >> $GITHUB_STEP_SUMMARY fi echo "| **Git Commit** | ${{ github.sha }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Triggered By** | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Triggered By** | ${GITHUB_ACTOR} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### โœ… Sync Complete" >> $GITHUB_STEP_SUMMARY echo "Your AEM project has been successfully synced to Cloud Manager." >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/aws-cdk.yml b/.github/workflows/aws-cdk.yml index 9de05a8..d349d2b 100644 --- a/.github/workflows/aws-cdk.yml +++ b/.github/workflows/aws-cdk.yml @@ -118,6 +118,7 @@ jobs: uses: actions/checkout@v6 with: lfs: ${{ inputs.lfs }} + persist-credentials: false - name: Detect Node.js version id: node-version @@ -188,14 +189,14 @@ jobs: - name: Install dependencies run: | - echo "๐Ÿ“ฆ Installing dependencies with ${{ steps.detect-package-manager.outputs.manager }}..." + echo "๐Ÿ“ฆ Installing dependencies with ${STEPS_DETECT_PACKAGE_MANAGER_OUTPUTS_MANAGER}..." verbose="" if [ "${{ inputs.debug }}" = "true" ]; then verbose="--verbose" fi - case "${{ steps.detect-package-manager.outputs.manager }}" in + case "${STEPS_DETECT_PACKAGE_MANAGER_OUTPUTS_MANAGER}" in "npm") npm ci $verbose ;; @@ -209,39 +210,49 @@ jobs: pnpm install --frozen-lockfile $verbose ;; esac + env: + STEPS_DETECT_PACKAGE_MANAGER_OUTPUTS_MANAGER: ${{ steps.detect-package-manager.outputs.manager }} - name: Set CDK commands id: parse-cdk-config run: | echo "โœ… CDK commands:" - echo " bootstrap: ${{ inputs.bootstrap-command }}" - echo " synth: ${{ inputs.synth-command }}" - echo " diff: ${{ inputs.diff-command }}" - echo " deploy: ${{ inputs.deploy-command }}" - - echo "bootstrap-cmd=${{ inputs.bootstrap-command }}" >> $GITHUB_OUTPUT - echo "synth-cmd=${{ inputs.synth-command }}" >> $GITHUB_OUTPUT - echo "diff-cmd=${{ inputs.diff-command }}" >> $GITHUB_OUTPUT - echo "deploy-cmd=${{ inputs.deploy-command }}" >> $GITHUB_OUTPUT + echo " bootstrap: ${INPUTS_BOOTSTRAP_COMMAND}" + echo " synth: ${INPUTS_SYNTH_COMMAND}" + echo " diff: ${INPUTS_DIFF_COMMAND}" + echo " deploy: ${INPUTS_DEPLOY_COMMAND}" + + echo "bootstrap-cmd=${INPUTS_BOOTSTRAP_COMMAND}" >> $GITHUB_OUTPUT + echo "synth-cmd=${INPUTS_SYNTH_COMMAND}" >> $GITHUB_OUTPUT + echo "diff-cmd=${INPUTS_DIFF_COMMAND}" >> $GITHUB_OUTPUT + echo "deploy-cmd=${INPUTS_DEPLOY_COMMAND}" >> $GITHUB_OUTPUT + env: + INPUTS_BOOTSTRAP_COMMAND: ${{ inputs.bootstrap-command }} + INPUTS_SYNTH_COMMAND: ${{ inputs.synth-command }} + INPUTS_DIFF_COMMAND: ${{ inputs.diff-command }} + INPUTS_DEPLOY_COMMAND: ${{ inputs.deploy-command }} - name: Resolve stack name id: resolve-stack-name run: | # Input takes priority over variable - if [ -n "${{ inputs.stack-name }}" ]; then - STACK_NAME="${{ inputs.stack-name }}" + if [ -n "${INPUTS_STACK_NAME}" ]; then + STACK_NAME="${INPUTS_STACK_NAME}" else - STACK_NAME="${{ vars.STACK_NAME }}" + STACK_NAME="${VARS_STACK_NAME}" fi echo "stack-name=$STACK_NAME" >> $GITHUB_OUTPUT + env: + INPUTS_STACK_NAME: ${{ inputs.stack-name }} + VARS_STACK_NAME: ${{ vars.STACK_NAME }} - name: Validate required inputs run: | echo "๐Ÿ” Validating deployment configuration..." - ENVIRONMENT="${{ inputs.github-environment }}" - STACK_NAME="${{ steps.resolve-stack-name.outputs.stack-name }}" - AWS_ACCESS_KEY_ID="${{ vars.AWS_ACCESS_KEY_ID }}" + ENVIRONMENT="${INPUTS_GITHUB_ENVIRONMENT}" + STACK_NAME="${STEPS_RESOLVE_STACK_NAME_OUTPUTS_STACK_NAME}" + AWS_ACCESS_KEY_ID="${VARS_AWS_ACCESS_KEY_ID}" AWS_SECRET_ACCESS_KEY="${{ secrets.AWS_SECRET_ACCESS_KEY }}" if [ -z "$ENVIRONMENT" ]; then @@ -272,9 +283,9 @@ jobs: echo "โœ… AWS_SECRET_ACCESS_KEY secret is configured" # Validate environment target - case "${{ inputs.environment-target }}" in + case "${INPUTS_ENVIRONMENT_TARGET}" in stg|prd|dev) - echo "โœ… Environment target: ${{ inputs.environment-target }}" + echo "โœ… Environment target: ${INPUTS_ENVIRONMENT_TARGET}" ;; "") echo "โ„น๏ธ Environment target is empty" @@ -286,8 +297,8 @@ jobs: esac # Validate context JSON if provided - if [ "${{ inputs.context-values }}" != "{}" ]; then - echo '${{ inputs.context-values }}' | jq . > /dev/null + if [ "${INPUTS_CONTEXT_VALUES}" != "{}" ]; then + echo '${INPUTS_CONTEXT_VALUES}' | jq . > /dev/null if [ $? -ne 0 ]; then echo "โŒ Error: context-values must be valid JSON" exit 1 @@ -303,6 +314,12 @@ jobs: fi echo "โœ… All inputs validated successfully" + env: + INPUTS_GITHUB_ENVIRONMENT: ${{ inputs.github-environment }} + STEPS_RESOLVE_STACK_NAME_OUTPUTS_STACK_NAME: ${{ steps.resolve-stack-name.outputs.stack-name }} + VARS_AWS_ACCESS_KEY_ID: ${{ vars.AWS_ACCESS_KEY_ID }} + INPUTS_ENVIRONMENT_TARGET: ${{ inputs.environment-target }} + INPUTS_CONTEXT_VALUES: ${{ inputs.context-values }} - name: Configure CDK context id: context-config @@ -312,23 +329,28 @@ jobs: context_args="" # Add environment-specific context - context_args="$context_args --context environment=${{ inputs.environment-target }}" + context_args="$context_args --context environment=${INPUTS_ENVIRONMENT_TARGET}" # Add custom context values (using process substitution to avoid subshell) - if [ "${{ inputs.context-values }}" != "{}" ]; then + if [ "${INPUTS_CONTEXT_VALUES}" != "{}" ]; then while read -r ctx; do context_args="$context_args $ctx" - done < <(echo '${{ inputs.context-values }}' | jq -r 'to_entries[] | "--context \(.key)=\(.value)"') + done < <(echo '${INPUTS_CONTEXT_VALUES}' | jq -r 'to_entries[] | "--context \(.key)=\(.value)"') fi echo "args=$context_args" >> $GITHUB_OUTPUT echo "โœ… Context arguments configured" + env: + INPUTS_ENVIRONMENT_TARGET: ${{ inputs.environment-target }} + INPUTS_CONTEXT_VALUES: ${{ inputs.context-values }} - name: Sanitise stack name id: sanitise run: | - sanitised_cdk_stack_name=$(echo "${{ steps.resolve-stack-name.outputs.stack-name }}" | tr -cd '[:alnum:]-_') + sanitised_cdk_stack_name=$(echo "${STEPS_RESOLVE_STACK_NAME_OUTPUTS_STACK_NAME}" | tr -cd '[:alnum:]-_') echo "sanitised-cdk-stack-name=$sanitised_cdk_stack_name" >> $GITHUB_OUTPUT + env: + STEPS_RESOLVE_STACK_NAME_OUTPUTS_STACK_NAME: ${{ steps.resolve-stack-name.outputs.stack-name }} - name: Package node_modules for artifact run: | @@ -356,6 +378,7 @@ jobs: uses: actions/checkout@v6 with: lfs: ${{ inputs.lfs }} + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -388,7 +411,7 @@ jobs: echo "โœ… node_modules extracted" - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v6 + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 with: aws-access-key-id: ${{ vars.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -405,7 +428,7 @@ jobs: verbose="--verbose" fi - BOOTSTRAP_CMD="${{ needs.prepare.outputs.cdk-bootstrap-cmd }}" + BOOTSTRAP_CMD="${NEEDS_PREPARE_OUTPUTS_CDK_BOOTSTRAP_CMD}" # Check if using custom command from config or default if [ "$BOOTSTRAP_CMD" = "npx cdk bootstrap" ]; then @@ -416,14 +439,18 @@ jobs: fi $BOOTSTRAP_CMD \ - aws://$(aws sts get-caller-identity --query Account --output text)/${{ inputs.aws-region }} \ + aws://$(aws sts get-caller-identity --query Account --output text)/${INPUTS_AWS_REGION} \ $role_args \ $verbose else - $BOOTSTRAP_CMD ${{ inputs.extra-arguments }} $verbose + $BOOTSTRAP_CMD ${INPUTS_EXTRA_ARGUMENTS} $verbose fi echo "โœ… CDK environment bootstrapped successfully" + env: + NEEDS_PREPARE_OUTPUTS_CDK_BOOTSTRAP_CMD: ${{ needs.prepare.outputs.cdk-bootstrap-cmd }} + INPUTS_AWS_REGION: ${{ inputs.aws-region }} + INPUTS_EXTRA_ARGUMENTS: ${{ inputs.extra-arguments }} - name: Synthesize CDK application if: inputs.synth == true @@ -435,14 +462,19 @@ jobs: verbose="--verbose" fi - SYNTH_CMD="${{ needs.prepare.outputs.cdk-synth-cmd }}" + SYNTH_CMD="${NEEDS_PREPARE_OUTPUTS_CDK_SYNTH_CMD}" - $SYNTH_CMD ${{ needs.prepare.outputs.stack-name }} \ - ${{ needs.prepare.outputs.context-args }} \ - ${{ inputs.extra-arguments }} \ + $SYNTH_CMD ${NEEDS_PREPARE_OUTPUTS_STACK_NAME} \ + ${NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS} \ + ${INPUTS_EXTRA_ARGUMENTS} \ $verbose echo "โœ… CDK synthesis completed successfully" + env: + NEEDS_PREPARE_OUTPUTS_CDK_SYNTH_CMD: ${{ needs.prepare.outputs.cdk-synth-cmd }} + NEEDS_PREPARE_OUTPUTS_STACK_NAME: ${{ needs.prepare.outputs.stack-name }} + NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS: ${{ needs.prepare.outputs.context-args }} + INPUTS_EXTRA_ARGUMENTS: ${{ inputs.extra-arguments }} - name: Upload synthesis artifacts if: inputs.synth == true @@ -458,11 +490,11 @@ jobs: run: | echo "๐Ÿ“Š Analysing deployment changes..." - DIFF_CMD="${{ needs.prepare.outputs.cdk-diff-cmd }}" + DIFF_CMD="${NEEDS_PREPARE_OUTPUTS_CDK_DIFF_CMD}" - diff_output=$($DIFF_CMD ${{ needs.prepare.outputs.stack-name }} \ - ${{ needs.prepare.outputs.context-args }} \ - ${{ inputs.extra-arguments }} \ + diff_output=$($DIFF_CMD ${NEEDS_PREPARE_OUTPUTS_STACK_NAME} \ + ${NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS} \ + ${INPUTS_EXTRA_ARGUMENTS} \ --no-color 2>&1 || true) # Save diff to file for analysis @@ -486,6 +518,11 @@ jobs: echo "โš ๏ธ Infrastructure changes detected!" echo "$diff_output" fi + env: + NEEDS_PREPARE_OUTPUTS_CDK_DIFF_CMD: ${{ needs.prepare.outputs.cdk-diff-cmd }} + NEEDS_PREPARE_OUTPUTS_STACK_NAME: ${{ needs.prepare.outputs.stack-name }} + NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS: ${{ needs.prepare.outputs.context-args }} + INPUTS_EXTRA_ARGUMENTS: ${{ inputs.extra-arguments }} - name: Upload diff analysis if: inputs.diff == true @@ -504,13 +541,13 @@ jobs: verbose="--verbose" fi - echo "๐Ÿš€ Deploying CDK stack: ${{ needs.prepare.outputs.stack-name }}" + echo "๐Ÿš€ Deploying CDK stack: ${NEEDS_PREPARE_OUTPUTS_STACK_NAME}" - DEPLOY_CMD="${{ needs.prepare.outputs.cdk-deploy-cmd }}" + DEPLOY_CMD="${NEEDS_PREPARE_OUTPUTS_CDK_DEPLOY_CMD}" - $DEPLOY_CMD ${{ needs.prepare.outputs.stack-name }} \ - ${{ needs.prepare.outputs.context-args }} \ - ${{ inputs.extra-arguments }} \ + $DEPLOY_CMD ${NEEDS_PREPARE_OUTPUTS_STACK_NAME} \ + ${NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS} \ + ${INPUTS_EXTRA_ARGUMENTS} \ --require-approval never \ --outputs-file stack-outputs.json \ $verbose @@ -526,6 +563,11 @@ jobs: echo "status=success" >> $GITHUB_OUTPUT echo "โœ… Stack deployed successfully" + env: + NEEDS_PREPARE_OUTPUTS_STACK_NAME: ${{ needs.prepare.outputs.stack-name }} + NEEDS_PREPARE_OUTPUTS_CDK_DEPLOY_CMD: ${{ needs.prepare.outputs.cdk-deploy-cmd }} + NEEDS_PREPARE_OUTPUTS_CONTEXT_ARGS: ${{ needs.prepare.outputs.context-args }} + INPUTS_EXTRA_ARGUMENTS: ${{ inputs.extra-arguments }} - name: Upload deployment artifacts if: inputs.deploy == true && steps.deploy.outputs.status == 'success' @@ -540,13 +582,21 @@ jobs: run: | echo "๐Ÿ“‹ Deployment Summary" echo "====================" - echo "Stack Pattern: ${{ needs.prepare.outputs.stack-name }}" + echo "Stack Pattern: ${NEEDS_PREPARE_OUTPUTS_STACK_NAME}" - echo "Environment: ${{ inputs.github-environment }}" - echo "Region: ${{ inputs.aws-region }}" - echo "Status: ${{ steps.deploy.outputs.status }}" - echo "Node Version: ${{ needs.prepare.outputs.node-version }}" - echo "Package Manager: ${{ needs.prepare.outputs.package-manager }}" + echo "Environment: ${INPUTS_GITHUB_ENVIRONMENT}" + echo "Region: ${INPUTS_AWS_REGION}" + echo "Status: ${STEPS_DEPLOY_OUTPUTS_STATUS}" + echo "Node Version: ${NEEDS_PREPARE_OUTPUTS_NODE_VERSION}" + echo "Package Manager: ${NEEDS_PREPARE_OUTPUTS_PACKAGE_MANAGER}" echo "" echo "๐ŸŽ‰ Deployment completed successfully!" + + env: + NEEDS_PREPARE_OUTPUTS_STACK_NAME: ${{ needs.prepare.outputs.stack-name }} + INPUTS_GITHUB_ENVIRONMENT: ${{ inputs.github-environment }} + INPUTS_AWS_REGION: ${{ inputs.aws-region }} + STEPS_DEPLOY_OUTPUTS_STATUS: ${{ steps.deploy.outputs.status }} + NEEDS_PREPARE_OUTPUTS_NODE_VERSION: ${{ needs.prepare.outputs.node-version }} + NEEDS_PREPARE_OUTPUTS_PACKAGE_MANAGER: ${{ needs.prepare.outputs.package-manager }} diff --git a/.github/workflows/changeset-check.yml b/.github/workflows/changeset-check.yml index 9cadace..d8e1de9 100644 --- a/.github/workflows/changeset-check.yml +++ b/.github/workflows/changeset-check.yml @@ -51,6 +51,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -74,7 +76,7 @@ jobs: - name: Run pre-install commands if: inputs.pre-install-commands != '' run: | - echo "${{ inputs.pre-install-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_PRE_INSTALL_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" @@ -82,20 +84,22 @@ jobs: done env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PRE_INSTALL_COMMANDS: ${{ inputs.pre-install-commands }} - name: Install dependencies run: | debug=${{ inputs.debug && '--verbose' || '' }} - if [ "${{ inputs.package-manager }}" = "yarn" ]; then + if [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then lock_flag=${{ inputs.is-yarn-classic && '--frozen-lockfile' || '--immutable' }} yarn install $lock_flag $debug - elif [ "${{ inputs.package-manager }}" = "pnpm" ]; then + elif [ "${INPUTS_PACKAGE_MANAGER}" = "pnpm" ]; then pnpm install --frozen-lockfile $debug else npm ci $debug fi env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} - name: Get Changed Files id: changed-files @@ -115,10 +119,12 @@ jobs: id: changeset-check env: CHANGED_FILES: ${{ steps.changed-files.outputs.result }} + INPUTS_PACKAGES_PATH: ${{ inputs.packages-path }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} run: | set +e - PACKAGES_PATH="${{ inputs.packages-path }}" + PACKAGES_PATH="${INPUTS_PACKAGES_PATH}" PACKAGES_PREFIX="${PACKAGES_PATH%/}" # Get changed directories under the packages path using GitHub API results @@ -167,7 +173,7 @@ jobs: fi # Check changeset status for detailed coverage - CHANGESET_STATUS=$(${{ inputs.package-manager }} changeset status --output=json 2>/dev/null) + CHANGESET_STATUS=$(${INPUTS_PACKAGE_MANAGER} changeset status --output=json 2>/dev/null) CHANGESET_EXIT_CODE=$? if [ $CHANGESET_EXIT_CODE -ne 0 ]; then @@ -198,12 +204,16 @@ jobs: - name: Comment on PR if no changeset if: steps.changeset-check.outputs.needs_changeset == 'true' uses: actions/github-script@v8 + env: + COMMENT_HEADER: ${{ inputs.comment-header }} + CHANGESET_COMMAND: ${{ inputs.changeset-command }} + STATUS_COMMAND: ${{ inputs.changeset-status-command }} with: - script: | + script: | # zizmor: ignore[template-injection] - affected_packages is a trusted input source const { owner, repo, number } = context.issue; - const commentHeader = `${{ inputs.comment-header }}`; - const changesetCmd = `${{ inputs.changeset-command }}`; - const statusCmd = `${{ inputs.changeset-status-command }}`; + const commentHeader = process.env.COMMENT_HEADER; + const changesetCmd = process.env.CHANGESET_COMMAND; + const statusCmd = process.env.STATUS_COMMAND; const comments = await github.rest.issues.listComments({ owner, repo, issue_number: number, @@ -274,10 +284,12 @@ jobs: - name: Remove changeset comment if changeset exists if: steps.changeset-check.outputs.needs_changeset == 'false' uses: actions/github-script@v8 + env: + COMMENT_HEADER: ${{ inputs.comment-header }} with: script: | const { owner, repo, number } = context.issue; - const commentHeader = `${{ inputs.comment-header }}`; + const commentHeader = process.env.COMMENT_HEADER; const comments = await github.rest.issues.listComments({ owner, repo, issue_number: number, diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index 46891d5..cd48af6 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -78,6 +78,7 @@ jobs: uses: actions/checkout@v6 with: token: ${{ secrets.GITHUB_PAT || github.token }} + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -102,7 +103,7 @@ jobs: - name: Run pre-install commands if: inputs.pre-install-commands != '' run: | - echo "${{ inputs.pre-install-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_PRE_INSTALL_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" @@ -110,25 +111,27 @@ jobs: done env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PRE_INSTALL_COMMANDS: ${{ inputs.pre-install-commands }} - name: Install dependencies run: | debug=${{ inputs.debug && '--verbose' || '' }} - if [ "${{ inputs.package-manager }}" = "yarn" ]; then + if [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then lock_flag=${{ inputs.is-yarn-classic && '--frozen-lockfile' || '--immutable' }} yarn install $lock_flag $debug - elif [ "${{ inputs.package-manager }}" = "pnpm" ]; then + elif [ "${INPUTS_PACKAGE_MANAGER}" = "pnpm" ]; then pnpm install --frozen-lockfile $debug else npm ci $debug fi env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} - name: Run pre-publish commands if: inputs.pre-publish-commands != '' run: | - echo "${{ inputs.pre-publish-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_PRE_PUBLISH_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" @@ -136,6 +139,7 @@ jobs: done env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PRE_PUBLISH_COMMANDS: ${{ inputs.pre-publish-commands }} - name: Configure Git run: | @@ -160,12 +164,14 @@ jobs: if: steps.changesets.outputs.published == 'true' run: | echo "Published packages:" - echo '${{ steps.changesets.outputs.publishedPackages }}' | jq -r '.[] | "- \(.name)@\(.version)"' + echo '${STEPS_CHANGESETS_OUTPUTS_PUBLISHEDPACKAGES}' | jq -r '.[] | "- \(.name)@\(.version)"' + env: + STEPS_CHANGESETS_OUTPUTS_PUBLISHEDPACKAGES: ${{ steps.changesets.outputs.publishedPackages }} - name: Run post-publish commands if: steps.changesets.outputs.published == 'true' && inputs.post-publish-commands != '' run: | - echo "${{ inputs.post-publish-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_POST_PUBLISH_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" @@ -173,3 +179,4 @@ jobs: done env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_POST_PUBLISH_COMMANDS: ${{ inputs.post-publish-commands }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 119897b..1e1fec3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: actions: read # only needed for private or internal repos steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: yamllint run: yamllint . diff --git a/.github/workflows/gadget-deploy.yml b/.github/workflows/gadget-deploy.yml index 716987a..a3ec177 100644 --- a/.github/workflows/gadget-deploy.yml +++ b/.github/workflows/gadget-deploy.yml @@ -50,6 +50,8 @@ jobs: if: inputs.push-staging == true steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Install ggt run: | @@ -60,7 +62,10 @@ jobs: id: push-environment working-directory: ${{ inputs.working-directory }} run: | - ggt push --app=${{ inputs.app-name }} --env=${{ inputs.environment-name }} --force --allow-unknown-directory + ggt push --app=${INPUTS_APP_NAME} --env=${INPUTS_ENVIRONMENT_NAME} --force --allow-unknown-directory + env: + INPUTS_APP_NAME: ${{ inputs.app-name }} + INPUTS_ENVIRONMENT_NAME: ${{ inputs.environment-name }} test: name: ๐Ÿงช Test from Gadget @@ -71,6 +76,8 @@ jobs: if: inputs.test == true steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Install ggt run: | @@ -80,7 +87,10 @@ jobs: - name: Pull client files into env # pull .gadget folder into test runner working-directory: ${{ inputs.working-directory }} run: | - ggt pull --app=${{ inputs.app-name }} --env=${{ inputs.environment-name }} --force --allow-unknown-directory + ggt pull --app=${INPUTS_APP_NAME} --env=${INPUTS_ENVIRONMENT_NAME} --force --allow-unknown-directory + env: + INPUTS_APP_NAME: ${{ inputs.app-name }} + INPUTS_ENVIRONMENT_NAME: ${{ inputs.environment-name }} - name: Setup Node.js uses: actions/setup-node@v6 @@ -113,6 +123,8 @@ jobs: if: inputs.deploy-production == true steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Install ggt run: | @@ -123,6 +135,10 @@ jobs: working-directory: ${{ inputs.working-directory }} run: | ggt deploy \ - --app=${{ inputs.app-name }} \ - --env=${{ inputs.environment-name }} \ + --app=${INPUTS_APP_NAME} \ + --env=${INPUTS_ENVIRONMENT_NAME} \ --force --allow-unknown-directory --allow-problems + + env: + INPUTS_APP_NAME: ${{ inputs.app-name }} + INPUTS_ENVIRONMENT_NAME: ${{ inputs.environment-name }} diff --git a/.github/workflows/magento-cloud-deploy.yml b/.github/workflows/magento-cloud-deploy.yml index 5c77099..6e65222 100644 --- a/.github/workflows/magento-cloud-deploy.yml +++ b/.github/workflows/magento-cloud-deploy.yml @@ -77,24 +77,29 @@ jobs: steps: - name: Validate required inputs run: | - if [ -z "${{ inputs.magento-cloud-project-id }}" ]; then + if [ -z "${INPUTS_MAGENTO_CLOUD_PROJECT_ID}" ]; then echo "โŒ Error: magento-cloud-project-id is required" exit 1 fi - if [ "${{ inputs.environment }}" != "integration" ] && \ - [ "${{ inputs.environment }}" != "staging" ] && \ - [ "${{ inputs.environment }}" != "production" ]; then + if [ "${INPUTS_ENVIRONMENT}" != "integration" ] && \ + [ "${INPUTS_ENVIRONMENT}" != "staging" ] && \ + [ "${INPUTS_ENVIRONMENT}" != "production" ]; then echo "โŒ Error: environment must be one of: integration, staging, production" exit 1 fi echo "โœ… All required inputs validated" + env: + INPUTS_MAGENTO_CLOUD_PROJECT_ID: ${{ inputs.magento-cloud-project-id }} + INPUTS_ENVIRONMENT: ${{ inputs.environment }} - name: Create NewRelic deployment marker (start) if: inputs.newrelic-app-id != '' env: NEWRELIC_API_KEY: ${{ secrets.newrelic-api-key }} + INPUTS_NEWRELIC_APP_ID: ${{ inputs.newrelic-app-id }} + INPUTS_ENVIRONMENT: ${{ inputs.environment }} run: | if [ -z "$NEWRELIC_API_KEY" ]; then echo "โ„น๏ธ NewRelic API key not configured, skipping deployment marker" @@ -103,15 +108,15 @@ jobs: echo "๐Ÿ“Š Creating NewRelic deployment marker (start)..." - curl -X POST "https://api.newrelic.com/v2/applications/${{ inputs.newrelic-app-id }}/deployments.json" \ + curl -X POST "https://api.newrelic.com/v2/applications/${INPUTS_NEWRELIC_APP_ID}/deployments.json" \ -H "X-Api-Key: $NEWRELIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "deployment": { "revision": "${{ github.sha }}", "changelog": "Magento Cloud deployment started", - "description": "Deployment to ${{ inputs.environment }} environment", - "user": "${{ github.actor }}" + "description": "Deployment to ${INPUTS_ENVIRONMENT} environment", + "user": "${GITHUB_ACTOR}" } }' @@ -121,6 +126,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 # Full git history required for Magento Cloud + persist-credentials: false - name: Install Magento Cloud CLI run: | @@ -136,7 +142,7 @@ jobs: - name: Deploy to Magento Cloud id: deployment run: | - echo "๐Ÿš€ Starting deployment to ${{ inputs.environment }}..." + echo "๐Ÿš€ Starting deployment to ${INPUTS_ENVIRONMENT}..." debug="" if [ "${{ inputs.debug }}" = "true" ]; then @@ -144,10 +150,10 @@ jobs: fi # Set project context - magento-cloud project:set-remote "${{ inputs.magento-cloud-project-id }}" + magento-cloud project:set-remote "${INPUTS_MAGENTO_CLOUD_PROJECT_ID}" # Deploy based on environment type - case "${{ inputs.environment }}" in + case "${INPUTS_ENVIRONMENT}" in "integration") # Push to integration environment echo "Deploying to integration environment..." @@ -155,13 +161,16 @@ jobs: ;; "staging"|"production") # Push to staging/production branch - echo "Deploying to ${{ inputs.environment }} environment..." - magento-cloud push --environment "${{ inputs.environment }}" --force --wait $debug + echo "Deploying to ${INPUTS_ENVIRONMENT} environment..." + magento-cloud push --environment "${INPUTS_ENVIRONMENT}" --force --wait $debug ;; esac echo "โœ… Deployment completed successfully" echo "deployment-success=true" >> $GITHUB_OUTPUT + env: + INPUTS_ENVIRONMENT: ${{ inputs.environment }} + INPUTS_MAGENTO_CLOUD_PROJECT_ID: ${{ inputs.magento-cloud-project-id }} - name: Get deployment information id: deploy-info @@ -170,14 +179,14 @@ jobs: # Get environment URL URL=$(magento-cloud url \ - --environment "${{ inputs.environment }}" \ - --project "${{ inputs.magento-cloud-project-id }}" \ + --environment "${INPUTS_ENVIRONMENT}" \ + --project "${INPUTS_MAGENTO_CLOUD_PROJECT_ID}" \ --pipe | tr -d '[:space:]') echo "url=$URL" >> "$GITHUB_OUTPUT" # Get deployment ID DEPLOYMENT_ID=$(magento-cloud activity:list \ - --environment "${{ inputs.environment }}" \ + --environment "${INPUTS_ENVIRONMENT}" \ --type push --limit 1 --format csv \ --columns id --no-header | head -1) echo "id=$DEPLOYMENT_ID" >> "$GITHUB_OUTPUT" @@ -187,24 +196,27 @@ jobs: echo " URL: ${URL}" echo " Deployment ID: ${DEPLOYMENT_ID}" fi + env: + INPUTS_ENVIRONMENT: ${{ inputs.environment }} + INPUTS_MAGENTO_CLOUD_PROJECT_ID: ${{ inputs.magento-cloud-project-id }} - name: Generate deployment summary run: | - DEPLOY_URL="${{ steps.deploy-info.outputs.url }}" + DEPLOY_URL="${STEPS_DEPLOY_INFO_OUTPUTS_URL}" echo "## ๐Ÿ›๏ธ Magento Cloud Deployment Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY - echo "| **Project ID** | ${{ inputs.magento-cloud-project-id }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Environment** | ${{ inputs.environment }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Deployment ID** | ${{ steps.deploy-info.outputs.id }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Project ID** | ${INPUTS_MAGENTO_CLOUD_PROJECT_ID} |" >> $GITHUB_STEP_SUMMARY + echo "| **Environment** | ${INPUTS_ENVIRONMENT} |" >> $GITHUB_STEP_SUMMARY + echo "| **Deployment ID** | ${STEPS_DEPLOY_INFO_OUTPUTS_ID} |" >> $GITHUB_STEP_SUMMARY echo "| **Site URL** | [$DEPLOY_URL]($DEPLOY_URL) |" >> $GITHUB_STEP_SUMMARY echo "| **Git Commit** | ${{ github.sha }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Deployed By** | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Deployed By** | ${GITHUB_ACTOR} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - case "${{ inputs.environment }}" in + case "${INPUTS_ENVIRONMENT}" in "production") echo "### ๐ŸŒ Production Deployment" >> $GITHUB_STEP_SUMMARY echo "Your Magento store is now live at:" >> $GITHUB_STEP_SUMMARY @@ -221,11 +233,20 @@ jobs: echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY ;; esac + env: + STEPS_DEPLOY_INFO_OUTPUTS_URL: ${{ steps.deploy-info.outputs.url }} + INPUTS_MAGENTO_CLOUD_PROJECT_ID: ${{ inputs.magento-cloud-project-id }} + INPUTS_ENVIRONMENT: ${{ inputs.environment }} + STEPS_DEPLOY_INFO_OUTPUTS_ID: ${{ steps.deploy-info.outputs.id }} - name: Create NewRelic deployment marker (complete) if: inputs.newrelic-app-id != '' env: NEWRELIC_API_KEY: ${{ secrets.newrelic-api-key }} + STEPS_DEPLOYMENT_OUTCOME: ${{ steps.deployment.outcome }} + INPUTS_ENVIRONMENT: ${{ inputs.environment }} + STEPS_DEPLOY_INFO_OUTPUTS_URL: ${{ steps.deploy-info.outputs.url }} + INPUTS_NEWRELIC_APP_ID: ${{ inputs.newrelic-app-id }} run: | if [ -z "$NEWRELIC_API_KEY" ]; then echo "โ„น๏ธ NewRelic API key not configured, skipping deployment marker" @@ -235,25 +256,25 @@ jobs: echo "๐Ÿ“Š Creating NewRelic deployment marker (complete)..." # Determine deployment status based on previous step outcomes - if [ "${{ steps.deployment.outcome }}" == "success" ]; then + if [ "${STEPS_DEPLOYMENT_OUTCOME}" == "success" ]; then CHANGELOG="Magento Cloud deployment completed successfully" - DESCRIPTION="Deployment to ${{ inputs.environment }} completed at ${{ steps.deploy-info.outputs.url }}" + DESCRIPTION="Deployment to ${INPUTS_ENVIRONMENT} completed at ${STEPS_DEPLOY_INFO_OUTPUTS_URL}" echo "โœ… Deployment was successful" - elif [ "${{ steps.deployment.outcome }}" == "failure" ]; then + elif [ "${STEPS_DEPLOYMENT_OUTCOME}" == "failure" ]; then CHANGELOG="Magento Cloud deployment failed" - DESCRIPTION="Deployment to ${{ inputs.environment }} failed - check workflow logs for details" + DESCRIPTION="Deployment to ${INPUTS_ENVIRONMENT} failed - check workflow logs for details" echo "โŒ Deployment failed" - elif [ "${{ steps.deployment.outcome }}" == "cancelled" ]; then + elif [ "${STEPS_DEPLOYMENT_OUTCOME}" == "cancelled" ]; then CHANGELOG="Magento Cloud deployment cancelled" - DESCRIPTION="Deployment to ${{ inputs.environment }} was cancelled by user" + DESCRIPTION="Deployment to ${INPUTS_ENVIRONMENT} was cancelled by user" echo "โš ๏ธ Deployment was cancelled" else - CHANGELOG="Magento Cloud deployment status: ${{ steps.deployment.outcome }}" - DESCRIPTION="Deployment to ${{ inputs.environment }} ended with status: ${{ steps.deployment.outcome }}" - echo "โ„น๏ธ Deployment status: ${{ steps.deployment.outcome }}" + CHANGELOG="Magento Cloud deployment status: ${STEPS_DEPLOYMENT_OUTCOME}" + DESCRIPTION="Deployment to ${INPUTS_ENVIRONMENT} ended with status: ${STEPS_DEPLOYMENT_OUTCOME}" + echo "โ„น๏ธ Deployment status: ${STEPS_DEPLOYMENT_OUTCOME}" fi - curl -X POST "https://api.newrelic.com/v2/applications/${{ inputs.newrelic-app-id }}/deployments.json" \ + curl -X POST "https://api.newrelic.com/v2/applications/${INPUTS_NEWRELIC_APP_ID}/deployments.json" \ -H "X-Api-Key: $NEWRELIC_API_KEY" \ -H "Content-Type: application/json" \ -d "{ @@ -261,28 +282,28 @@ jobs: \"revision\": \"${{ github.sha }}\", \"changelog\": \"${CHANGELOG}\", \"description\": \"${DESCRIPTION}\", - \"user\": \"${{ github.actor }}\" + \"user\": \"${GITHUB_ACTOR}\" } }" - echo "โœ… NewRelic deployment marker created with status: ${{ steps.deployment.outcome }}" + echo "โœ… NewRelic deployment marker created with status: ${STEPS_DEPLOYMENT_OUTCOME}" - name: Report deployment to CST if: steps.deployment.outcome == 'success' run: | # Determine CST endpoint - input overrides workspace variable - CST_ENDPOINT="${{ inputs.cst-endpoint }}" + CST_ENDPOINT="${INPUTS_CST_ENDPOINT}" if [ -z "$CST_ENDPOINT" ]; then - CST_ENDPOINT="${{ vars.CST_ENDPOINT }}" + CST_ENDPOINT="${VARS_CST_ENDPOINT}" fi # Determine CST project key - input overrides workspace variable, defaults to repo name - CST_PROJECT_KEY="${{ inputs.cst-project-key }}" + CST_PROJECT_KEY="${INPUTS_CST_PROJECT_KEY}" if [ -z "$CST_PROJECT_KEY" ]; then - CST_PROJECT_KEY="${{ vars.CST_PROJECT_KEY }}" + CST_PROJECT_KEY="${VARS_CST_PROJECT_KEY}" fi if [ -z "$CST_PROJECT_KEY" ]; then - CST_PROJECT_KEY="${{ github.event.repository.name }}" + CST_PROJECT_KEY="${GITHUB_EVENT_REPOSITORY_NAME}" fi # Determine CST reporting key - input overrides workspace secret @@ -301,13 +322,13 @@ jobs: fi # Determine CST branch - input overrides default branch - CST_BRANCH="${{ inputs.cst-branch }}" + CST_BRANCH="${INPUTS_CST_BRANCH}" if [ -z "$CST_BRANCH" ]; then - CST_BRANCH="${{ github.event.repository.default_branch }}" + CST_BRANCH="${GITHUB_EVENT_REPOSITORY_DEFAULT_BRANCH}" fi # Only report when deploying from the target branch - CURRENT_BRANCH="${{ github.ref_name }}" + CURRENT_BRANCH="${GITHUB_REF_NAME}" if [ "$CURRENT_BRANCH" != "$CST_BRANCH" ]; then echo "โ„น๏ธ CST reporting skipped (branch '${CURRENT_BRANCH}' does not match target '${CST_BRANCH}')" exit 0 @@ -329,3 +350,12 @@ jobs: else echo "โš ๏ธ composer.lock not found, skipping CST reporting" fi + + env: + INPUTS_CST_ENDPOINT: ${{ inputs.cst-endpoint }} + VARS_CST_ENDPOINT: ${{ vars.CST_ENDPOINT }} + INPUTS_CST_PROJECT_KEY: ${{ inputs.cst-project-key }} + VARS_CST_PROJECT_KEY: ${{ vars.CST_PROJECT_KEY }} + GITHUB_EVENT_REPOSITORY_NAME: ${{ github.event.repository.name }} + INPUTS_CST_BRANCH: ${{ inputs.cst-branch }} + GITHUB_EVENT_REPOSITORY_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} diff --git a/.github/workflows/node-pr.yml b/.github/workflows/node-pr.yml index c9232c4..a4407fb 100644 --- a/.github/workflows/node-pr.yml +++ b/.github/workflows/node-pr.yml @@ -107,6 +107,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: ${{ inputs.fetch-depth }} + persist-credentials: false - name: Install Node.js uses: actions/setup-node@v6 with: @@ -160,16 +161,18 @@ jobs: if: inputs.pre-install-commands != '' run: | # Execute pre-install commands line by line - echo "${{ inputs.pre-install-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_PRE_INSTALL_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" fi done + env: + INPUTS_PRE_INSTALL_COMMANDS: ${{ inputs.pre-install-commands }} - name: Install dependencies run: | debug=${{ inputs.debug && '--verbose' || '' }} - if [ "${{ inputs.package-manager }}" = "yarn" ]; then + if [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then lock_dependencies=${{ inputs.is-yarn-classic && '--frozen-lockfile' || '--immutable' }} skip_cache=${{ inputs.skip-cache && '--force' || '' }} @@ -179,6 +182,9 @@ jobs: npm ci $debug fi + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + # 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/ @@ -200,6 +206,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: ${{ inputs.fetch-depth }} + persist-credentials: false - name: Fetch Origin run: git fetch origin - name: Install Node.js @@ -253,29 +260,36 @@ jobs: flush_var - name: Register problem matchers - uses: aligent/workflows/.github/actions/node-problem-matchers@main + uses: aligent/workflows/.github/actions/node-problem-matchers@main # zizmor: ignore[unpinned-uses] trusted - name: Check build command exists id: check-build - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] trusted source with: command: ${{ inputs.build-command }} - name: Build (script) if: steps.check-build.outputs.exists-script == 'true' - run: ${{ inputs.package-manager }} run ${{ inputs.build-command }} ${{ inputs.debug && '--verbose' || '' }} + run: ${INPUTS_PACKAGE_MANAGER} run ${INPUTS_BUILD_COMMAND} ${{ inputs.debug && '--verbose' || '' }} + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_BUILD_COMMAND: ${{ inputs.build-command }} - name: Build (nx) if: steps.check-build.outputs.exists-script != 'true' && steps.check-build.outputs.exists-nx-target == 'true' - run: npx nx run-many -t ${{ inputs.build-command }} ${{ inputs.debug && '--verbose' || '' }} + run: npx nx run-many -t ${INPUTS_BUILD_COMMAND} ${{ inputs.debug && '--verbose' || '' }} + env: + INPUTS_BUILD_COMMAND: ${{ inputs.build-command }} - name: Skip build (command not found) if: steps.check-build.outputs.exists-script != 'true' && steps.check-build.outputs.exists-nx-target != 'true' - run: echo "Build command '${{ inputs.build-command }}' not found, skipping" + run: echo "Build command '${INPUTS_BUILD_COMMAND}' not found, skipping" + env: + INPUTS_BUILD_COMMAND: ${{ inputs.build-command }} - name: Remove problem matchers if: always() - uses: aligent/workflows/.github/actions/node-problem-matchers@main + uses: aligent/workflows/.github/actions/node-problem-matchers@main # zizmor: ignore[unpinned-uses] trusted with: action: remove @@ -296,6 +310,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: ${{ inputs.fetch-depth }} + persist-credentials: false - name: Fetch Origin run: git fetch origin - name: Install Node.js @@ -350,40 +365,43 @@ jobs: - name: Run pre-test command if: inputs.pre-test-command != '' - run: ${{ inputs.package-manager }} run ${{ inputs.pre-test-command }} + run: ${INPUTS_PACKAGE_MANAGER} run ${INPUTS_PRE_TEST_COMMAND} + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_PRE_TEST_COMMAND: ${{ inputs.pre-test-command }} - name: Check test command exists id: check-test if: inputs.skip-test == false - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] - trusted source with: command: ${{ inputs.test-command }} - name: Check lint command exists id: check-lint if: inputs.skip-lint == false - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] - trusted source with: command: ${{ inputs.lint-command }} - name: Check format command exists id: check-format if: inputs.skip-format == false - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] - trusted source with: command: ${{ inputs.format-command }} - name: Check test-storybook command exists id: check-test-storybook if: inputs.skip-test-storybook == false - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] - trusted source with: command: ${{ inputs.test-storybook-command }} - name: Check check-types command exists id: check-check-types if: inputs.skip-check-types == false - uses: aligent/workflows/.github/actions/command-exists@main + uses: aligent/workflows/.github/actions/command-exists@main # zizmor: ignore[unpinned-uses] - trusted source with: command: ${{ inputs.check-types-command }} @@ -391,35 +409,47 @@ jobs: id: build-commands run: | commands=() - if [ "${{ inputs.skip-test }}" != "true" ] && [ "${{ steps.check-test.outputs.exists }}" == "true" ]; then - commands+=("${{ inputs.test-command }}") + if [ "${{ inputs.skip-test }}" != "true" ] && [ "${STEPS_CHECK_TEST_OUTPUTS_EXISTS}" == "true" ]; then + commands+=("${INPUTS_TEST_COMMAND}") fi - if [ "${{ inputs.skip-lint }}" != "true" ] && [ "${{ steps.check-lint.outputs.exists }}" == "true" ]; then - commands+=("${{ inputs.lint-command }}") + if [ "${{ inputs.skip-lint }}" != "true" ] && [ "${STEPS_CHECK_LINT_OUTPUTS_EXISTS}" == "true" ]; then + commands+=("${INPUTS_LINT_COMMAND}") fi - if [ "${{ inputs.skip-format }}" != "true" ] && [ "${{ steps.check-format.outputs.exists }}" == "true" ]; then - commands+=("${{ inputs.format-command }}") + if [ "${{ inputs.skip-format }}" != "true" ] && [ "${STEPS_CHECK_FORMAT_OUTPUTS_EXISTS}" == "true" ]; then + commands+=("${INPUTS_FORMAT_COMMAND}") fi if [ "${{ inputs.skip-test-storybook }}" != "true" ] && \ - [ "${{ steps.check-test-storybook.outputs.exists }}" == "true" ]; then + [ "${STEPS_CHECK_TEST_STORYBOOK_OUTPUTS_EXISTS}" == "true" ]; then # Ensure playwright dependencies are installed before story blok test execution begins - if [ "${{ inputs.package-manager }}" = "yarn" ]; then + if [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then yarn playwright install --with-deps else npx playwright install --with-deps fi - commands+=("${{ inputs.test-storybook-command }}") + commands+=("${INPUTS_TEST_STORYBOOK_COMMAND}") fi if [ "${{ inputs.skip-check-types }}" != "true" ] && \ - [ "${{ steps.check-check-types.outputs.exists }}" == "true" ]; then - commands+=("${{ inputs.check-types-command }}") + [ "${STEPS_CHECK_CHECK_TYPES_OUTPUTS_EXISTS}" == "true" ]; then + commands+=("${INPUTS_CHECK_TYPES_COMMAND}") fi # Convert to JSON array json=$(printf '%s\n' "${commands[@]}" | jq -R . | jq -s -c .) echo "commands=$json" >> $GITHUB_OUTPUT + env: + STEPS_CHECK_TEST_OUTPUTS_EXISTS: ${{ steps.check-test.outputs.exists }} + INPUTS_TEST_COMMAND: ${{ inputs.test-command }} + STEPS_CHECK_LINT_OUTPUTS_EXISTS: ${{ steps.check-lint.outputs.exists }} + INPUTS_LINT_COMMAND: ${{ inputs.lint-command }} + STEPS_CHECK_FORMAT_OUTPUTS_EXISTS: ${{ steps.check-format.outputs.exists }} + INPUTS_FORMAT_COMMAND: ${{ inputs.format-command }} + STEPS_CHECK_TEST_STORYBOOK_OUTPUTS_EXISTS: ${{ steps.check-test-storybook.outputs.exists }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_TEST_STORYBOOK_COMMAND: ${{ inputs.test-storybook-command }} + STEPS_CHECK_CHECK_TYPES_OUTPUTS_EXISTS: ${{ steps.check-check-types.outputs.exists }} + INPUTS_CHECK_TYPES_COMMAND: ${{ inputs.check-types-command }} - name: Run checks concurrently - uses: aligent/workflows/.github/actions/run-checks@main + uses: aligent/workflows/.github/actions/run-checks@main # zizmor: ignore[unpinned-uses] - trusted source with: package-manager: ${{ inputs.package-manager }} debug: ${{ inputs.debug }} diff --git a/.github/workflows/nx-serverless-deployment.yml b/.github/workflows/nx-serverless-deployment.yml index 07654f6..e423f86 100644 --- a/.github/workflows/nx-serverless-deployment.yml +++ b/.github/workflows/nx-serverless-deployment.yml @@ -33,6 +33,8 @@ jobs: environment: ${{ inputs.environment }} steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Validate required inputs run: | @@ -106,16 +108,18 @@ jobs: lock_dependencies="--immutable" if [ "${{ inputs.is-yarn-classic }}" = "true" ]; then lock_dependencies="--frozen-lockfile" - elif [ "${{ inputs.package-manager }}" = "yarn" ]; then + elif [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then debug="" fi - if [ "${{ inputs.package-manager }}" = "yarn" ]; then + if [ "${INPUTS_PACKAGE_MANAGER}" = "yarn" ]; then yarn config get nodeLinker yarn install $lock_dependencies $debug else npm ci $debug fi + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} - name: ๐Ÿ” Check repository type id: repo-type @@ -148,7 +152,7 @@ jobs: # Insert the cfnRole value into all serverless files # yq v4 converts YAML merge keys (<<) to !!merge tags when writing, # which is invalid for serverless. Pipe through sed to strip them. - if [ "${{ steps.repo-type.outputs.is_monorepo }}" = "true" ]; then + if [ "${STEPS_REPO_TYPE_OUTPUTS_IS_MONOREPO}" = "true" ]; then find services/*/ -name serverless.yml -exec sh -c ' yq ".provider.cfnRole = \"${0}\"" "$1" | sed "s/!!merge < "$1.tmp" && mv "$1.tmp" "$1" ' "$CFN_ROLE" {} \; @@ -163,6 +167,7 @@ jobs: AWS_REGION: ${{ vars.AWS_REGION || 'ap-southeast-2' }} CFN_ROLE: ${{ vars.CFN_ROLE }} DEBUG: ${{ inputs.debug }} + STEPS_REPO_TYPE_OUTPUTS_IS_MONOREPO: ${{ steps.repo-type.outputs.is_monorepo }} - name: ๐Ÿš€ Deploy run: | @@ -173,7 +178,7 @@ jobs: verbose="--verbose" fi - if [ "${{ steps.repo-type.outputs.is_monorepo }}" = "true" ]; then + if [ "${STEPS_REPO_TYPE_OUTPUTS_IS_MONOREPO}" = "true" ]; then echo "Deploying monorepo..." npx nx run-many -t "$COMMAND" $verbose -- --stage "$STAGE" else @@ -184,3 +189,5 @@ jobs: STAGE: ${{ vars.STAGE }} AWS_REGION: ${{ vars.AWS_REGION || 'ap-southeast-2' }} DEBUG: ${{ inputs.debug }} + + STEPS_REPO_TYPE_OUTPUTS_IS_MONOREPO: ${{ steps.repo-type.outputs.is_monorepo }} diff --git a/.github/workflows/php-quality-checks.yml b/.github/workflows/php-quality-checks.yml index e5aa921..9f0c45c 100644 --- a/.github/workflows/php-quality-checks.yml +++ b/.github/workflows/php-quality-checks.yml @@ -155,6 +155,8 @@ jobs: COMPOSER_AUTH: ${{ secrets.composer-auth }} steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Check for required files id: check-files @@ -261,8 +263,10 @@ jobs: --dev \ --no-progress \ --no-interaction \ - ${{ inputs.composer-args }} \ + ${INPUTS_COMPOSER_ARGS} \ ${{ inputs.debug && '--verbose' || '' }} + env: + INPUTS_COMPOSER_ARGS: ${{ inputs.composer-args }} - name: Run Magento setup if needed if: steps.check-files.outputs.has-composer == 'true' @@ -331,6 +335,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -380,7 +386,7 @@ jobs: - name: Run PHPStan analysis run: | - echo "๐Ÿ” Running PHPStan analysis (Level ${{ inputs.phpstan-level }})..." + echo "๐Ÿ” Running PHPStan analysis (Level ${INPUTS_PHPSTAN_LEVEL})..." # Check for custom phpstan script first if composer run-script --list | grep -q "phpstan"; then @@ -395,14 +401,14 @@ jobs: phpstan_cmd="vendor/bin/phpstan" # Build PHPStan command - cmd="php -d memory_limit=${{ inputs.memory-limit }} $phpstan_cmd analyse" + cmd="php -d memory_limit=${INPUTS_MEMORY_LIMIT} $phpstan_cmd analyse" # Use existing config or set defaults - if [ "${{ needs.install.outputs.has-phpstan-config }}" = "true" ]; then + if [ "${NEEDS_INSTALL_OUTPUTS_HAS_PHPSTAN_CONFIG}" = "true" ]; then echo "โœ… Using existing PHPStan configuration" else echo "โ„น๏ธ Using default PHPStan configuration" - cmd="$cmd --level=${{ inputs.phpstan-level }} src/ app/" + cmd="$cmd --level=${INPUTS_PHPSTAN_LEVEL} src/ app/" fi # Add debug flags if enabled @@ -418,8 +424,8 @@ jobs: phpstan_cmd="phpstan" # Build PHPStan command - cmd="php -d memory_limit=${{ inputs.memory-limit }} $phpstan_cmd analyse" - cmd="$cmd --level=${{ inputs.phpstan-level }} src/ app/" + cmd="php -d memory_limit=${INPUTS_MEMORY_LIMIT} $phpstan_cmd analyse" + cmd="$cmd --level=${INPUTS_PHPSTAN_LEVEL} src/ app/" # Add debug flags if enabled if [ "${{ inputs.debug }}" = "true" ]; then @@ -430,6 +436,11 @@ jobs: eval $cmd fi + env: + INPUTS_PHPSTAN_LEVEL: ${{ inputs.phpstan-level }} + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} + NEEDS_INSTALL_OUTPUTS_HAS_PHPSTAN_CONFIG: ${{ needs.install.outputs.has-phpstan-config }} + # PHP CodeSniffer style checks phpcs: name: ๐ŸŽจ Code Style Check @@ -440,6 +451,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -480,13 +493,13 @@ jobs: - name: Run PHP CodeSniffer run: | - echo "๐ŸŽจ Running PHP CodeSniffer (${{ inputs.coding-standard }} standard)..." + echo "๐ŸŽจ Running PHP CodeSniffer (${INPUTS_CODING_STANDARD} standard)..." # Check for custom check-style script first if composer run-script --list | grep -q "check-style"; then echo "โœ… Using composer check-style script" composer run-script check-style - elif [ "${{ needs.install.outputs.has-phpcs-config }}" = "true" ]; then + elif [ "${NEEDS_INSTALL_OUTPUTS_HAS_PHPCS_CONFIG}" = "true" ]; then echo "โœ… Using existing PHPCS configuration" if [ -f "vendor/bin/phpcs" ]; then phpcs_cmd="vendor/bin/phpcs" @@ -496,18 +509,18 @@ jobs: phpcs_cmd="phpcs" fi - cmd="php -d memory_limit=${{ inputs.memory-limit }} $phpcs_cmd --report=full --colors" + cmd="php -d memory_limit=${INPUTS_MEMORY_LIMIT} $phpcs_cmd --report=full --colors" if [ "${{ inputs.debug }}" = "true" ]; then cmd="$cmd --verbose" fi eval $cmd elif [ -f "vendor/bin/phpcs" ]; then - echo "โœ… Using vendor PHPCS with ${{ inputs.coding-standard }} standard" + echo "โœ… Using vendor PHPCS with ${INPUTS_CODING_STANDARD} standard" phpcs_cmd="vendor/bin/phpcs" # Build PHPCS command - cmd="php -d memory_limit=${{ inputs.memory-limit }} $phpcs_cmd" - cmd="$cmd --standard=${{ inputs.coding-standard }} src/ app/" + cmd="php -d memory_limit=${INPUTS_MEMORY_LIMIT} $phpcs_cmd" + cmd="$cmd --standard=${INPUTS_CODING_STANDARD} src/ app/" cmd="$cmd --report=full --colors" if [ "${{ inputs.debug }}" = "true" ]; then @@ -521,13 +534,13 @@ jobs: phpcs_cmd="phpcs" # Install Magento2 standard if needed - if [ "${{ inputs.coding-standard }}" = "Magento2" ]; then + if [ "${INPUTS_CODING_STANDARD}" = "Magento2" ]; then composer global require magento/magento-coding-standard:* fi # Build PHPCS command - cmd="php -d memory_limit=${{ inputs.memory-limit }} $phpcs_cmd" - cmd="$cmd --standard=${{ inputs.coding-standard }} src/ app/" + cmd="php -d memory_limit=${INPUTS_MEMORY_LIMIT} $phpcs_cmd" + cmd="$cmd --standard=${INPUTS_CODING_STANDARD} src/ app/" cmd="$cmd --report=full --colors" if [ "${{ inputs.debug }}" = "true" ]; then @@ -537,6 +550,11 @@ jobs: eval $cmd fi + env: + INPUTS_CODING_STANDARD: ${{ inputs.coding-standard }} + NEEDS_INSTALL_OUTPUTS_HAS_PHPCS_CONFIG: ${{ needs.install.outputs.has-phpcs-config }} + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} + # PHPUnit testing with coverage test: name: ๐Ÿงช Unit Tests @@ -548,6 +566,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP with Xdebug uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -603,7 +623,7 @@ jobs: pushd dev/tests/unit # Build PHPUnit command with coverage - cmd='php -d memory_limit=${{ inputs.memory-limit }}' + cmd='php -d memory_limit=${INPUTS_MEMORY_LIMIT}' cmd+=' -d xdebug.mode=coverage $phpunit_cmd' cmd+=' -c ./phpunit.xml --testsuite="Unit Tests"' cmd+=' --log-junit ./test-results/report.xml' @@ -616,10 +636,12 @@ jobs: # Execute PHPUnit eval $cmd + env: + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} - name: Check coverage threshold run: | - threshold=${{ inputs.coverage-threshold }} + threshold=${INPUTS_COVERAGE_THRESHOLD} if [ -f "coverage.xml" ] && [ "$threshold" != "0" ]; then echo "๐Ÿ“Š Checking coverage threshold ($threshold%)..." @@ -645,6 +667,8 @@ jobs: else echo "โ„น๏ธ Skipping coverage threshold check" fi + env: + INPUTS_COVERAGE_THRESHOLD: ${{ inputs.coverage-threshold }} - name: Upload coverage reports uses: actions/upload-artifact@v7 @@ -713,6 +737,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -762,7 +788,7 @@ jobs: # Run integration tests if [ -f "vendor/bin/phpunit" ]; then - php -d memory_limit=${{ inputs.memory-limit }} vendor/bin/phpunit \ + php -d memory_limit=${INPUTS_MEMORY_LIMIT} vendor/bin/phpunit \ -c $(pwd)/dev/tests/integration/phpunit.xml \ --log-junit ./test-results/integration-report.xml \ --testsuite="Integration Tests" \ @@ -771,6 +797,8 @@ jobs: echo "โŒ PHPUnit not found in vendor/bin/" exit 1 fi + env: + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} - name: Upload test results uses: actions/upload-artifact@v7 @@ -831,6 +859,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -896,7 +926,7 @@ jobs: # Run REST API tests if [ -f "vendor/bin/phpunit" ]; then - php -d memory_limit=${{ inputs.memory-limit }} vendor/bin/phpunit \ + php -d memory_limit=${INPUTS_MEMORY_LIMIT} vendor/bin/phpunit \ -c $(pwd)/dev/tests/api-functional/phpunit_rest.xml \ --log-junit ./test-results/rest-api-report.xml \ --testsuite="REST API Tests" \ @@ -910,6 +940,8 @@ jobs: if [ ! -z "$SERVER_PID" ]; then kill $SERVER_PID || true fi + env: + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} - name: Upload test results uses: actions/upload-artifact@v7 @@ -970,6 +1002,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@93cb3149d228516dfca679606c5060ee44f46437 @@ -1035,7 +1069,7 @@ jobs: # Run GraphQL tests if [ -f "vendor/bin/phpunit" ]; then - php -d memory_limit=${{ inputs.memory-limit }} vendor/bin/phpunit \ + php -d memory_limit=${INPUTS_MEMORY_LIMIT} vendor/bin/phpunit \ -c $(pwd)/dev/tests/api-functional/phpunit_graphql.xml \ --log-junit ./test-results/graphql-report.xml \ --testsuite="GraphQL API Tests" \ @@ -1049,6 +1083,8 @@ jobs: if [ ! -z "$SERVER_PID" ]; then kill $SERVER_PID || true fi + env: + INPUTS_MEMORY_LIMIT: ${{ inputs.memory-limit }} - name: Upload test results uses: actions/upload-artifact@v7 diff --git a/.github/workflows/pwa-deployment.yml b/.github/workflows/pwa-deployment.yml index fd5f91f..1026d39 100644 --- a/.github/workflows/pwa-deployment.yml +++ b/.github/workflows/pwa-deployment.yml @@ -124,7 +124,7 @@ jobs: - name: Configure cache strategy id: cache-config run: | - case "${{ inputs.cache-strategy }}" in + case "${INPUTS_CACHE_STRATEGY}" in "immutable") # Static assets with content hashing - cache for 1 year echo "cache-control-static=public, max-age=31536000, immutable" >> $GITHUB_OUTPUT @@ -137,20 +137,23 @@ jobs: echo "cache-control-html=no-cache, no-store, must-revalidate" >> $GITHUB_OUTPUT ;; *) - echo "โŒ Invalid cache-strategy: '${{ inputs.cache-strategy }}'. Must be 'immutable' or 'no-cache'." + echo "โŒ Invalid cache-strategy: '${INPUTS_CACHE_STRATEGY}'. Must be 'immutable' or 'no-cache'." exit 1 ;; esac # Prepare invalidation paths - echo "invalidation-paths=${{ inputs.cloudfront-invalidation-paths }}" >> $GITHUB_OUTPUT + echo "invalidation-paths=${INPUTS_CLOUDFRONT_INVALIDATION_PATHS}" >> $GITHUB_OUTPUT if [ "${{ inputs.debug }}" = "true" ]; then echo "๐Ÿ” Cache configuration:" - echo " Strategy: ${{ inputs.cache-strategy }}" + echo " Strategy: ${INPUTS_CACHE_STRATEGY}" echo " Static assets: $(cat $GITHUB_OUTPUT | grep cache-control-static | cut -d'=' -f2-)" echo " HTML files: $(cat $GITHUB_OUTPUT | grep cache-control-html | cut -d'=' -f2-)" fi + env: + INPUTS_CACHE_STRATEGY: ${{ inputs.cache-strategy }} + INPUTS_CLOUDFRONT_INVALIDATION_PATHS: ${{ inputs.cloudfront-invalidation-paths }} - name: Configure deployment paths id: deployment-config @@ -160,25 +163,25 @@ jobs: if [ -n "${{ github.event.pull_request.number }}" ]; then PREFIX="pr-${{ github.event.pull_request.number }}" else - PREFIX="branch-$(echo '${{ github.ref_name }}' | sed 's/[^a-zA-Z0-9-]/-/g')" + PREFIX="branch-$(echo '${GITHUB_REF_NAME}' | sed 's/[^a-zA-Z0-9-]/-/g')" fi echo "s3-prefix=${PREFIX}/" >> $GITHUB_OUTPUT - if [ -n "${{ inputs.preview-base-url }}" ]; then - echo "deployment-url=${{ inputs.preview-base-url }}/${PREFIX}/" >> $GITHUB_OUTPUT + if [ -n "${INPUTS_PREVIEW_BASE_URL}" ]; then + echo "deployment-url=${INPUTS_PREVIEW_BASE_URL}/${PREFIX}/" >> $GITHUB_OUTPUT else - DEPLOY_URL="https://${{ inputs.s3-bucket }}.s3.amazonaws.com/${PREFIX}/index.html" + DEPLOY_URL="https://${INPUTS_S3_BUCKET}.s3.amazonaws.com/${PREFIX}/index.html" echo "deployment-url=$DEPLOY_URL" >> $GITHUB_OUTPUT fi else # Production/staging deployment to root echo "s3-prefix=" >> $GITHUB_OUTPUT - if [ -n "${{ inputs.preview-base-url }}" ]; then - echo "deployment-url=${{ inputs.preview-base-url }}/" >> $GITHUB_OUTPUT + if [ -n "${INPUTS_PREVIEW_BASE_URL}" ]; then + echo "deployment-url=${INPUTS_PREVIEW_BASE_URL}/" >> $GITHUB_OUTPUT else - echo "deployment-url=https://${{ inputs.s3-bucket }}.s3.amazonaws.com/index.html" >> $GITHUB_OUTPUT + echo "deployment-url=https://${INPUTS_S3_BUCKET}.s3.amazonaws.com/index.html" >> $GITHUB_OUTPUT fi fi @@ -187,18 +190,24 @@ jobs: echo " S3 Prefix: $(cat $GITHUB_OUTPUT | grep s3-prefix | cut -d'=' -f2-)" echo " Deployment URL: $(cat $GITHUB_OUTPUT | grep deployment-url | cut -d'=' -f2-)" fi + env: + INPUTS_PREVIEW_BASE_URL: ${{ inputs.preview-base-url }} + INPUTS_S3_BUCKET: ${{ inputs.s3-bucket }} - name: Configure multi-brand matrix id: brand-config run: | - if [ -n "${{ inputs.brand-config }}" ]; then - echo "matrix=${{ inputs.brand-config }}" >> $GITHUB_OUTPUT + if [ -n "${INPUTS_BRAND_CONFIG}" ]; then + echo "matrix=${INPUTS_BRAND_CONFIG}" >> $GITHUB_OUTPUT echo "๐Ÿ“ฑ Multi-brand deployment configured" else echo 'matrix={"brand":["default"]}' >> $GITHUB_OUTPUT echo "๐Ÿ“ฑ Single brand deployment" fi + env: + INPUTS_BRAND_CONFIG: ${{ inputs.brand-config }} + # Build and test the application build-and-deploy: name: ๐Ÿš€ Build Application and Deploy to AWS @@ -215,6 +224,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -229,7 +240,7 @@ jobs: debug="--verbose" fi - case "${{ inputs.package-manager }}" in + case "${INPUTS_PACKAGE_MANAGER}" in "yarn") if [ "${{ inputs.is-yarn-classic }}" = "true" ]; then yarn install --frozen-lockfile $debug @@ -241,10 +252,12 @@ jobs: npm ci $debug ;; *) - echo "โŒ Unsupported package manager: ${{ inputs.package-manager }}" + echo "โŒ Unsupported package manager: ${INPUTS_PACKAGE_MANAGER}" exit 1 ;; esac + env: + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} - name: Build application run: | @@ -254,18 +267,22 @@ jobs: fi # Set brand-specific environment if multi-brand - if [ "${{ matrix.brand }}" != "default" ]; then - echo "๐Ÿท๏ธ Building for brand: ${{ matrix.brand }}" - export BRAND=${{ matrix.brand }} + if [ "${MATRIX_BRAND}" != "default" ]; then + echo "๐Ÿท๏ธ Building for brand: ${MATRIX_BRAND}" + export BRAND=${MATRIX_BRAND} fi echo "๐Ÿ—๏ธ Building application..." - ${{ inputs.package-manager }} run ${{ inputs.build-command }} $debug + ${INPUTS_PACKAGE_MANAGER} run ${INPUTS_BUILD_COMMAND} $debug + env: + MATRIX_BRAND: ${{ matrix.brand }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_BUILD_COMMAND: ${{ inputs.build-command }} - name: Verify build output run: | - if [ ! -d "${{ inputs.build-directory }}" ]; then - echo "โŒ Build directory '${{ inputs.build-directory }}' not found" + if [ ! -d "${INPUTS_BUILD_DIRECTORY}" ]; then + echo "โŒ Build directory '${INPUTS_BUILD_DIRECTORY}' not found" echo "Available directories:" ls -la exit 1 @@ -273,10 +290,12 @@ jobs: echo "โœ… Build completed successfully" echo "๐Ÿ“ Build directory contents:" - find "${{ inputs.build-directory }}" -type f | head -10 + find "${INPUTS_BUILD_DIRECTORY}" -type f | head -10 + env: + INPUTS_BUILD_DIRECTORY: ${{ inputs.build-directory }} - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v6 + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 with: aws-access-key-id: ${{ secrets.aws-access-key-id }} aws-secret-access-key: ${{ secrets.aws-secret-access-key }} @@ -285,14 +304,18 @@ jobs: - name: Configure S3 deployment paths id: s3-config run: | - S3_PATH="${{ needs.prepare.outputs.s3-prefix }}" + S3_PATH="${NEEDS_PREPARE_OUTPUTS_S3_PREFIX}" - if [ "${{ matrix.brand }}" != "default" ]; then - S3_PATH="${S3_PATH}${{ matrix.brand }}/" + if [ "${MATRIX_BRAND}" != "default" ]; then + S3_PATH="${S3_PATH}${MATRIX_BRAND}/" fi echo "s3-path=${S3_PATH}" >> $GITHUB_OUTPUT - echo "๐ŸŽฏ Deploying to: s3://${{ inputs.s3-bucket }}/${S3_PATH}" + echo "๐ŸŽฏ Deploying to: s3://${INPUTS_S3_BUCKET}/${S3_PATH}" + env: + NEEDS_PREPARE_OUTPUTS_S3_PREFIX: ${{ needs.prepare.outputs.s3-prefix }} + MATRIX_BRAND: ${{ matrix.brand }} + INPUTS_S3_BUCKET: ${{ inputs.s3-bucket }} - name: Deploy static assets to S3 run: | @@ -300,13 +323,19 @@ jobs: # Deploy static assets with immutable cache headers (exclude HTML and service-worker.js) aws s3 sync \ - "${{ inputs.build-directory }}" \ - "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ + "${INPUTS_BUILD_DIRECTORY}" \ + "s3://${INPUTS_S3_BUCKET}/${STEPS_S3_CONFIG_OUTPUTS_S3_PATH}" \ --exclude "*.html" \ --exclude "service-worker.js" \ - --cache-control "${{ needs.prepare.outputs.cache-control-static }}" \ + --cache-control "${NEEDS_PREPARE_OUTPUTS_CACHE_CONTROL_STATIC}" \ --delete \ - ${{ inputs.extra-sync-args }} + ${INPUTS_EXTRA_SYNC_ARGS} + env: + INPUTS_BUILD_DIRECTORY: ${{ inputs.build-directory }} + INPUTS_S3_BUCKET: ${{ inputs.s3-bucket }} + STEPS_S3_CONFIG_OUTPUTS_S3_PATH: ${{ steps.s3-config.outputs.s3-path }} + NEEDS_PREPARE_OUTPUTS_CACHE_CONTROL_STATIC: ${{ needs.prepare.outputs.cache-control-static }} + INPUTS_EXTRA_SYNC_ARGS: ${{ inputs.extra-sync-args }} - name: Deploy HTML and service worker to S3 run: | @@ -314,29 +343,35 @@ jobs: # Deploy HTML and service-worker.js with revalidation cache headers aws s3 sync \ - "${{ inputs.build-directory }}" \ - "s3://${{ inputs.s3-bucket }}/${{ steps.s3-config.outputs.s3-path }}" \ + "${INPUTS_BUILD_DIRECTORY}" \ + "s3://${INPUTS_S3_BUCKET}/${STEPS_S3_CONFIG_OUTPUTS_S3_PATH}" \ --exclude "*" \ --include "*.html" \ --include "service-worker.js" \ - --cache-control "${{ needs.prepare.outputs.cache-control-html }}" \ - ${{ inputs.extra-sync-args }} + --cache-control "${NEEDS_PREPARE_OUTPUTS_CACHE_CONTROL_HTML}" \ + ${INPUTS_EXTRA_SYNC_ARGS} + env: + INPUTS_BUILD_DIRECTORY: ${{ inputs.build-directory }} + INPUTS_S3_BUCKET: ${{ inputs.s3-bucket }} + STEPS_S3_CONFIG_OUTPUTS_S3_PATH: ${{ steps.s3-config.outputs.s3-path }} + NEEDS_PREPARE_OUTPUTS_CACHE_CONTROL_HTML: ${{ needs.prepare.outputs.cache-control-html }} + INPUTS_EXTRA_SYNC_ARGS: ${{ inputs.extra-sync-args }} - name: Invalidate CloudFront cache run: | echo "๐Ÿ”„ Invalidating CloudFront cache..." # Parse invalidation paths - PATHS=$(echo '${{ needs.prepare.outputs.invalidation-paths }}' | jq -r '.[]') + PATHS=$(echo '${NEEDS_PREPARE_OUTPUTS_INVALIDATION_PATHS}' | jq -r '.[]') # Add brand prefix if multi-brand deployment - if [ "${{ matrix.brand }}" != "default" ]; then + if [ "${MATRIX_BRAND}" != "default" ]; then PREFIXED_PATHS="" for path in $PATHS; do if [ "$path" = "/*" ]; then - PREFIXED_PATHS="$PREFIXED_PATHS /${{ steps.s3-config.outputs.s3-path }}*" + PREFIXED_PATHS="$PREFIXED_PATHS /${STEPS_S3_CONFIG_OUTPUTS_S3_PATH}*" else - PREFIXED_PATHS="$PREFIXED_PATHS /${{ steps.s3-config.outputs.s3-path }}${path#/}" + PREFIXED_PATHS="$PREFIXED_PATHS /${STEPS_S3_CONFIG_OUTPUTS_S3_PATH}${path#/}" fi done PATHS="$PREFIXED_PATHS" @@ -345,7 +380,7 @@ jobs: echo "Invalidating paths: $PATHS" INVALIDATION_ID=$(aws cloudfront create-invalidation \ - --distribution-id "${{ inputs.cloudfront-distribution-id }}" \ + --distribution-id "${INPUTS_CLOUDFRONT_DISTRIBUTION_ID}" \ --paths $PATHS \ --query 'Invalidation.Id' \ --output text) @@ -355,10 +390,15 @@ jobs: if [ "${{ inputs.debug }}" = "true" ]; then echo "๐Ÿ” Waiting for invalidation to complete..." aws cloudfront wait invalidation-completed \ - --distribution-id "${{ inputs.cloudfront-distribution-id }}" \ + --distribution-id "${INPUTS_CLOUDFRONT_DISTRIBUTION_ID}" \ --id "$INVALIDATION_ID" echo "โœ… CloudFront invalidation completed" fi + env: + NEEDS_PREPARE_OUTPUTS_INVALIDATION_PATHS: ${{ needs.prepare.outputs.invalidation-paths }} + MATRIX_BRAND: ${{ matrix.brand }} + STEPS_S3_CONFIG_OUTPUTS_S3_PATH: ${{ steps.s3-config.outputs.s3-path }} + INPUTS_CLOUDFRONT_DISTRIBUTION_ID: ${{ inputs.cloudfront-distribution-id }} - name: Generate deployment summary run: | @@ -366,26 +406,37 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY - echo "| **Environment** | ${{ inputs.environment }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Brand** | ${{ matrix.brand }} |" >> $GITHUB_STEP_SUMMARY - echo "| **S3 Bucket** | ${{ inputs.s3-bucket }} |" >> $GITHUB_STEP_SUMMARY - echo "| **S3 Path** | ${{ steps.s3-config.outputs.s3-path }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Cache Strategy** | ${{ inputs.cache-strategy }} |" >> $GITHUB_STEP_SUMMARY - echo "| **Deployment URL** | ${{ needs.prepare.outputs.deployment-url }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Environment** | ${INPUTS_ENVIRONMENT} |" >> $GITHUB_STEP_SUMMARY + echo "| **Brand** | ${MATRIX_BRAND} |" >> $GITHUB_STEP_SUMMARY + echo "| **S3 Bucket** | ${INPUTS_S3_BUCKET} |" >> $GITHUB_STEP_SUMMARY + echo "| **S3 Path** | ${STEPS_S3_CONFIG_OUTPUTS_S3_PATH} |" >> $GITHUB_STEP_SUMMARY + echo "| **Cache Strategy** | ${INPUTS_CACHE_STRATEGY} |" >> $GITHUB_STEP_SUMMARY + echo "| **Deployment URL** | ${NEEDS_PREPARE_OUTPUTS_DEPLOYMENT_URL} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### ๐Ÿ“Š Build Information" >> $GITHUB_STEP_SUMMARY - echo "- **Package Manager**: ${{ inputs.package-manager }}" >> $GITHUB_STEP_SUMMARY - echo "- **Build Command**: ${{ inputs.build-command }}" >> $GITHUB_STEP_SUMMARY - echo "- **Build Directory**: ${{ inputs.build-directory }}" >> $GITHUB_STEP_SUMMARY + echo "- **Package Manager**: ${INPUTS_PACKAGE_MANAGER}" >> $GITHUB_STEP_SUMMARY + echo "- **Build Command**: ${INPUTS_BUILD_COMMAND}" >> $GITHUB_STEP_SUMMARY + echo "- **Build Directory**: ${INPUTS_BUILD_DIRECTORY}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - DEPLOY_URL="${{ needs.prepare.outputs.deployment-url }}" + DEPLOY_URL="${NEEDS_PREPARE_OUTPUTS_DEPLOYMENT_URL}" if [ "${{ inputs.preview-mode }}" = "true" ]; then echo "### ๐Ÿ” Preview Environment" >> $GITHUB_STEP_SUMMARY echo "This is a preview deployment. The application is available at:" >> $GITHUB_STEP_SUMMARY echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY else echo "### ๐ŸŒ Deployment" >> $GITHUB_STEP_SUMMARY - echo "Application deployed to ${{ inputs.environment }} environment:" >> $GITHUB_STEP_SUMMARY + echo "Application deployed to ${INPUTS_ENVIRONMENT} environment:" >> $GITHUB_STEP_SUMMARY echo "**[$DEPLOY_URL]($DEPLOY_URL)**" >> $GITHUB_STEP_SUMMARY fi + + env: + INPUTS_ENVIRONMENT: ${{ inputs.environment }} + MATRIX_BRAND: ${{ matrix.brand }} + INPUTS_S3_BUCKET: ${{ inputs.s3-bucket }} + STEPS_S3_CONFIG_OUTPUTS_S3_PATH: ${{ steps.s3-config.outputs.s3-path }} + INPUTS_CACHE_STRATEGY: ${{ inputs.cache-strategy }} + NEEDS_PREPARE_OUTPUTS_DEPLOYMENT_URL: ${{ needs.prepare.outputs.deployment-url }} + INPUTS_PACKAGE_MANAGER: ${{ inputs.package-manager }} + INPUTS_BUILD_COMMAND: ${{ inputs.build-command }} + INPUTS_BUILD_DIRECTORY: ${{ inputs.build-directory }} diff --git a/.github/workflows/s3-deploy.yml b/.github/workflows/s3-deploy.yml index 6ead1a5..af995b0 100644 --- a/.github/workflows/s3-deploy.yml +++ b/.github/workflows/s3-deploy.yml @@ -49,9 +49,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 + with: + persist-credentials: false - name: Configure AWS creds - uses: aws-actions/configure-aws-credentials@v6 + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 with: aws-access-key-id: ${{ inputs.aws-access-key-id }} aws-secret-access-key: ${{ secrets.aws-secret-access-key }} @@ -63,15 +65,21 @@ jobs: cache_control="" extra_args="" - if [ -n "${{inputs.cache-control}}" ]; then - cache_control="--cache-control \"${{inputs.cache-control}}\"" + if [ -n "${INPUTS_CACHE_CONTROL}" ]; then + cache_control="--cache-control \"${INPUTS_CACHE_CONTROL}\"" fi - command="aws s3 sync ${{inputs.local-path}}" - command="$command s3://${{inputs.s3-bucket}}${{inputs.s3-path}} ${cache_control} ${{inputs.extra-args}}" + command="aws s3 sync ${INPUTS_LOCAL_PATH}" + command="$command s3://${INPUTS_S3_BUCKET}${INPUTS_S3_PATH} ${cache_control} ${INPUTS_EXTRA_ARGS}" if [ "${{inputs.delete-flag}}" = "true" ]; then command="$command --delete" fi $command + env: + INPUTS_CACHE_CONTROL: ${{inputs.cache-control}} + INPUTS_LOCAL_PATH: ${{inputs.local-path}} + INPUTS_S3_BUCKET: ${{inputs.s3-bucket}} + INPUTS_S3_PATH: ${{inputs.s3-path}} + INPUTS_EXTRA_ARGS: ${{inputs.extra-args}} diff --git a/.github/workflows/shopify-deploy.yml b/.github/workflows/shopify-deploy.yml index 99915fc..5002962 100644 --- a/.github/workflows/shopify-deploy.yml +++ b/.github/workflows/shopify-deploy.yml @@ -48,6 +48,8 @@ jobs: - name: Checkout code uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -75,10 +77,13 @@ jobs: working-directory: ${{ inputs.working-directory }} run: | if [ "${{ inputs.deploy-production }}" = "true" ]; then - yarn shopify app config use ${{ inputs.production-toml-name }} + yarn shopify app config use ${INPUTS_PRODUCTION_TOML_NAME} else - yarn shopify app config use ${{ inputs.development-toml-name }} + yarn shopify app config use ${INPUTS_DEVELOPMENT_TOML_NAME} fi + env: + INPUTS_PRODUCTION_TOML_NAME: ${{ inputs.production-toml-name }} + INPUTS_DEVELOPMENT_TOML_NAME: ${{ inputs.development-toml-name }} - name: Deploy to Shopify working-directory: ${{ inputs.working-directory }} diff --git a/.github/workflows/static-hosting-deployment.yml b/.github/workflows/static-hosting-deployment.yml index 498ebf5..fa882ed 100644 --- a/.github/workflows/static-hosting-deployment.yml +++ b/.github/workflows/static-hosting-deployment.yml @@ -50,8 +50,13 @@ on: type: string required: false +permissions: {} + jobs: build-and-install: + permissions: + contents: read # for actions/checkout + checks: write # for problem matchers to post PR annotations uses: ./.github/workflows/node-pr.yml with: skip-format: true diff --git a/.github/workflows/update-lockfile.yml b/.github/workflows/update-lockfile.yml index 552a7d9..2fd8844 100644 --- a/.github/workflows/update-lockfile.yml +++ b/.github/workflows/update-lockfile.yml @@ -63,6 +63,7 @@ jobs: with: token: ${{ secrets.GITHUB_PAT || github.token }} ref: ${{ github.head_ref }} + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 @@ -86,7 +87,7 @@ jobs: - name: Run pre-install commands if: inputs.pre-install-commands != '' run: | - echo "${{ inputs.pre-install-commands }}" | while IFS= read -r cmd; do + echo "${INPUTS_PRE_INSTALL_COMMANDS}" | while IFS= read -r cmd; do if [ -n "$cmd" ]; then echo "Running: $cmd" eval "$cmd" @@ -94,28 +95,34 @@ jobs: done env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_PRE_INSTALL_COMMANDS: ${{ inputs.pre-install-commands }} - name: Update Lockfile run: | - ${{ inputs.update-command }} + ${INPUTS_UPDATE_COMMAND} - if git diff --quiet ${{ inputs.lockfile }}; then + if git diff --quiet ${INPUTS_LOCKFILE}; then echo "No lockfile changes needed" exit 0 fi env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + INPUTS_UPDATE_COMMAND: ${{ inputs.update-command }} + INPUTS_LOCKFILE: ${{ inputs.lockfile }} - name: Commit Lockfile Changes run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - if git diff --quiet ${{ inputs.lockfile }}; then + if git diff --quiet ${INPUTS_LOCKFILE}; then echo "No changes to commit" exit 0 fi - git add ${{ inputs.lockfile }} - git commit -m "${{ inputs.commit-message }}" + git add ${INPUTS_LOCKFILE} + git commit -m "${INPUTS_COMMIT_MESSAGE}" git push + env: + INPUTS_LOCKFILE: ${{ inputs.lockfile }} + INPUTS_COMMIT_MESSAGE: ${{ inputs.commit-message }} From 5c20896495b28f54e02847b962c78a34c6ef8ded Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Thu, 19 Mar 2026 09:40:17 +1030 Subject: [PATCH 7/8] Add instructions for installing linting tooling locally and taskfile for quick execution --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ Taskfile.yml | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Taskfile.yml diff --git a/README.md b/README.md index 1de32b4..815b9cf 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,52 @@ The three changeset workflows work together to automate package versioning, publ - [Changeset Check](docs/changeset-check.md) - advisory PR comments for missing changesets - [Update Lockfile](docs/update-lockfile.md) - auto-commits lockfile updates on version PRs +## Local Development + +### Prerequisites + +**yamllint** (via pip3): +```bash +pip3 install yamllint +# Add pip's user bin to your PATH if not already present (macOS) +export PATH="$PATH:$(python3 -m site --user-base)/bin" +# Add the export to ~/.zshrc or ~/.bash_profile to make it permanent +``` + +**actionlint** โ€” install the pre-built binary for your platform. +See the [actionlint install docs](https://github.com/rhysd/actionlint/blob/v1.7.11/docs/install.md) for all options. On macOS (Apple Silicon), download the `darwin-arm64` pre-built binary: + +```bash +# macOS (Apple Silicon) โ€” adjust version as needed +curl -sLO https://github.com/rhysd/actionlint/releases/download/v1.7.11/actionlint_1.7.11_darwin_arm64.tar.gz +tar -xzf actionlint_1.7.11_darwin_arm64.tar.gz actionlint +mv actionlint +``` + +**zizmor** โ€” security analysis for GitHub Actions. +See the [zizmor install docs](https://docs.zizmor.sh/installation/) for all options: + +```bash +pip3 install zizmor +``` + +**Task** โ€” task runner used to execute the checks. +See [taskfile.dev/docs/installation](https://taskfile.dev/docs/installation) for all options: + +```bash +# Install script โ€” place the binary somewhere in your $PATH (e.g. ~/bin) +sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/bin +``` + +### Running checks locally + +```bash +task # run all checks +task yamllint # YAML linting only +task actionlint # GitHub Actions linting only +task zizmor # security analysis only +``` + ## Test Github Workflows Locally using Act Refer to https://aligent.atlassian.net/wiki/x/JgDjAwE on guidance to test these Workflows locally diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..a754131 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,38 @@ +version: '3' + +tasks: + default: + desc: Run all CI checks + deps: [yamllint, actionlint, zizmor] + + yamllint: + desc: Lint YAML files + preconditions: + - sh: command -v yamllint + msg: "yamllint is not installed. Run: pip3 install yamllint" + cmds: + - yamllint . + + actionlint: + desc: Lint GitHub Actions workflow files + preconditions: + - sh: command -v actionlint + msg: "actionlint is not installed. See https://github.com/rhysd/actionlint/blob/main/docs/install.md" + cmds: + - actionlint + + zizmor: + desc: Run security analysis on GitHub Actions workflows + preconditions: + - sh: command -v zizmor + msg: "zizmor is not installed. Run: pip3 install zizmor" + cmds: + - zizmor .github/ + + zizmor-fix: + desc: Auto-fix zizmor security findings (safe fixes only) + preconditions: + - sh: command -v zizmor + msg: "zizmor is not installed. Run: pip3 install zizmor" + cmds: + - zizmor --fix .github/ From 9cacde508c1b47b9adc166102dfe1dae99146aad Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Thu, 19 Mar 2026 09:44:20 +1030 Subject: [PATCH 8/8] Replace all checkout actions with pinned commit hash --- .../workflows/aem-sync-to-cloudmanager-repo.yml | 6 +++--- .github/workflows/aws-cdk.yml | 4 ++-- .github/workflows/changeset-check.yml | 2 +- .github/workflows/changeset-release.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/gadget-deploy.yml | 6 +++--- .github/workflows/magento-cloud-deploy.yml | 2 +- .github/workflows/node-pr.yml | 6 +++--- .github/workflows/nx-serverless-deployment.yml | 2 +- .github/workflows/php-quality-checks.yml | 14 +++++++------- .github/workflows/pwa-deployment.yml | 2 +- .github/workflows/s3-deploy.yml | 2 +- .github/workflows/shopify-deploy.yml | 2 +- .github/workflows/update-lockfile.yml | 2 +- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/aem-sync-to-cloudmanager-repo.yml b/.github/workflows/aem-sync-to-cloudmanager-repo.yml index e00dc11..6d78427 100644 --- a/.github/workflows/aem-sync-to-cloudmanager-repo.yml +++ b/.github/workflows/aem-sync-to-cloudmanager-repo.yml @@ -96,7 +96,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -133,7 +133,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -169,7 +169,7 @@ jobs: steps: - name: Checkout code with full history - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/aws-cdk.yml b/.github/workflows/aws-cdk.yml index d349d2b..cdce6b7 100644 --- a/.github/workflows/aws-cdk.yml +++ b/.github/workflows/aws-cdk.yml @@ -115,7 +115,7 @@ jobs: cdk-deploy-cmd: ${{ steps.parse-cdk-config.outputs.deploy-cmd }} steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: lfs: ${{ inputs.lfs }} persist-credentials: false @@ -375,7 +375,7 @@ jobs: deployment-status: ${{ steps.deploy.outputs.status }} steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: lfs: ${{ inputs.lfs }} persist-credentials: false diff --git a/.github/workflows/changeset-check.yml b/.github/workflows/changeset-check.yml index d8e1de9..9d43cfb 100644 --- a/.github/workflows/changeset-check.yml +++ b/.github/workflows/changeset-check.yml @@ -50,7 +50,7 @@ jobs: pull-requests: write steps: - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index cd48af6..9cc2741 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -75,7 +75,7 @@ jobs: id-token: write steps: - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: token: ${{ secrets.GITHUB_PAT || github.token }} persist-credentials: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e1fec3..827aa48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: contents: read # only needed for private or internal repos actions: read # only needed for private or internal repos steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/gadget-deploy.yml b/.github/workflows/gadget-deploy.yml index a3ec177..a81dde2 100644 --- a/.github/workflows/gadget-deploy.yml +++ b/.github/workflows/gadget-deploy.yml @@ -49,7 +49,7 @@ jobs: push-environment-status: ${{ steps.push-environment.outcome }} if: inputs.push-staging == true steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -75,7 +75,7 @@ jobs: needs: push if: inputs.test == true steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -122,7 +122,7 @@ jobs: GGT_TOKEN: ${{ secrets.gadget-api-token }} if: inputs.deploy-production == true steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/magento-cloud-deploy.yml b/.github/workflows/magento-cloud-deploy.yml index 6e65222..cd9ea1d 100644 --- a/.github/workflows/magento-cloud-deploy.yml +++ b/.github/workflows/magento-cloud-deploy.yml @@ -123,7 +123,7 @@ jobs: echo "โœ… NewRelic deployment start marker created" - name: Checkout code with full git history - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 # Full git history required for Magento Cloud persist-credentials: false diff --git a/.github/workflows/node-pr.yml b/.github/workflows/node-pr.yml index a4407fb..15c694c 100644 --- a/.github/workflows/node-pr.yml +++ b/.github/workflows/node-pr.yml @@ -104,7 +104,7 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: ${{ inputs.fetch-depth }} persist-credentials: false @@ -203,7 +203,7 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_OPTIONS: ${{ inputs.node-options }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: ${{ inputs.fetch-depth }} persist-credentials: false @@ -307,7 +307,7 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_OPTIONS: ${{ inputs.node-options }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: ${{ inputs.fetch-depth }} persist-credentials: false diff --git a/.github/workflows/nx-serverless-deployment.yml b/.github/workflows/nx-serverless-deployment.yml index e423f86..0769527 100644 --- a/.github/workflows/nx-serverless-deployment.yml +++ b/.github/workflows/nx-serverless-deployment.yml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.environment }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/php-quality-checks.yml b/.github/workflows/php-quality-checks.yml index 9f0c45c..a8b8cd4 100644 --- a/.github/workflows/php-quality-checks.yml +++ b/.github/workflows/php-quality-checks.yml @@ -154,7 +154,7 @@ jobs: env: COMPOSER_AUTH: ${{ secrets.composer-auth }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -334,7 +334,7 @@ jobs: needs.install.outputs.has-composer == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -450,7 +450,7 @@ jobs: needs.install.outputs.has-composer == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -565,7 +565,7 @@ jobs: needs.install.outputs.has-unit-tests == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -736,7 +736,7 @@ jobs: --health-interval=10s --health-timeout=5s --health-retries=5 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -858,7 +858,7 @@ jobs: --health-interval=10s --health-timeout=5s --health-retries=5 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false @@ -1001,7 +1001,7 @@ jobs: --health-interval=10s --health-timeout=5s --health-retries=5 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/pwa-deployment.yml b/.github/workflows/pwa-deployment.yml index 1026d39..51390d1 100644 --- a/.github/workflows/pwa-deployment.yml +++ b/.github/workflows/pwa-deployment.yml @@ -223,7 +223,7 @@ jobs: matrix: ${{ fromJSON(needs.prepare.outputs.brand-matrix) }} steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/s3-deploy.yml b/.github/workflows/s3-deploy.yml index af995b0..01219a8 100644 --- a/.github/workflows/s3-deploy.yml +++ b/.github/workflows/s3-deploy.yml @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/shopify-deploy.yml b/.github/workflows/shopify-deploy.yml index 5002962..daa76d8 100644 --- a/.github/workflows/shopify-deploy.yml +++ b/.github/workflows/shopify-deploy.yml @@ -47,7 +47,7 @@ jobs: exit 1 - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: persist-credentials: false diff --git a/.github/workflows/update-lockfile.yml b/.github/workflows/update-lockfile.yml index 2fd8844..5419b59 100644 --- a/.github/workflows/update-lockfile.yml +++ b/.github/workflows/update-lockfile.yml @@ -59,7 +59,7 @@ jobs: pull-requests: write steps: - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: token: ${{ secrets.GITHUB_PAT || github.token }} ref: ${{ github.head_ref }}