Skip to content

chore(deps): update dependency @aws-sdk/client-cloudwatch to ^3.1049.0 #124

chore(deps): update dependency @aws-sdk/client-cloudwatch to ^3.1049.0

chore(deps): update dependency @aws-sdk/client-cloudwatch to ^3.1049.0 #124

Workflow file for this run

name: Smoke Pack
on:
pull_request:
paths:
- 'cloudformation/scenarios/**'
- 'tests/smoke/**'
- 'scripts/smoke*.sh'
- 'scripts/check-quarantines.mjs'
- 'playwright.config.ts'
- 'docs/smoke-test-account-config.yml'
- 'docs/smoke-test-account-setup.md'
- '.github/workflows/smoke.yml'
- 'package.json'
schedule:
- cron: '0 2 * * *'
push:
branches: [main]
workflow_dispatch:
permissions:
id-token: write
contents: read
issues: write
pull-requests: read
# Smoke must serialise: one smoke account can't absorb two parallel all-demo
# deploys. cancel-in-progress is false because cancelling the runner does not
# stop the in-flight CFN deploy on AWS side.
concurrency:
group: smoke
cancel-in-progress: false
env:
STACK_NAME: all-demo
AWS_REGION: us-east-1
jobs:
scope:
runs-on: ubuntu-latest
outputs:
mode: ${{ steps.decide.outputs.mode }}
scenarios: ${{ steps.decide.outputs.scenarios }}
override: ${{ steps.override.outputs.active }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- id: decide
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_BASE_REF: ${{ github.base_ref }}
run: ./scripts/smoke-scope.sh
# AC3.10: `smoke-override-emergency` label causes the smoke job to skip,
# making it a pass — so the merge gate clears. CODEOWNERS approval of the
# PR itself is required by repo branch-protection, not by this workflow.
# The 48h follow-up issue is opened by smoke-override-followup.yml.
- id: override
if: github.event_name == 'pull_request'
env:
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
run: |
if echo "$LABELS" | jq -re '.[]|select(.=="smoke-override-emergency")' >/dev/null; then
echo "active=true" >> "$GITHUB_OUTPUT"
echo "::warning::smoke-override-emergency label present — smoke gate bypassed."
else
echo "active=false" >> "$GITHUB_OUTPUT"
fi
smoke:
needs: scope
if: needs.scope.outputs.mode != 'none' && needs.scope.outputs.override != 'true'
runs-on: ubuntu-latest
timeout-minutes: 90
# smoke-test-deploy environment is gated by CODEOWNERS for non-main refs
# (configured in repo Settings → Environments).
environment: smoke-test-deploy
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install yq
run: |
YQ_VERSION="v4.45.4"
sudo wget -qO /usr/local/bin/yq \
"https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"
sudo chmod +x /usr/local/bin/yq
yq --version
- name: Read smoke-test-account-config.yml
id: cfg
run: |
yq -e '.smoke_test_account_id != "000000000000" and .smoke_test_account_id != null' docs/smoke-test-account-config.yml > /dev/null || {
echo "ERROR: docs/smoke-test-account-config.yml has placeholder values; account setup incomplete" >&2
exit 1
}
# runbook_version is informational — squash-merge SHA churn made it brittle to gate on.
RECORDED=$(yq -r '.runbook_version' docs/smoke-test-account-config.yml)
LATEST=$(git log -1 --pretty=%H -- docs/smoke-test-account-setup.md)
if [ "$RECORDED" != "$LATEST" ]; then
echo "::warning::runbook_version ($RECORDED) older than latest setup.md commit ($LATEST). Bump via: yq -i '.runbook_version = \"$LATEST\"' docs/smoke-test-account-config.yml"
fi
echo "account_id=$(yq -r '.smoke_test_account_id' docs/smoke-test-account-config.yml)" >> "$GITHUB_OUTPUT"
echo "role_arn=$(yq -r '.smoke_test_deploy_role_arn' docs/smoke-test-account-config.yml)" >> "$GITHUB_OUTPUT"
echo "region=$(yq -r '.smoke_test_region' docs/smoke-test-account-config.yml)" >> "$GITHUB_OUTPUT"
echo "aicc_phone_arn=$(yq -r '.aicc_existing_phone_number_arn' docs/smoke-test-account-config.yml)" >> "$GITHUB_OUTPUT"
echo "aicc_phone_number=$(yq -r '.aicc_existing_phone_number' docs/smoke-test-account-config.yml)" >> "$GITHUB_OUTPUT"
- uses: aws-actions/configure-aws-credentials@v6
id: aws-creds
with:
role-to-assume: ${{ steps.cfg.outputs.role_arn }}
role-session-name: smoke-${{ github.run_id }}
aws-region: ${{ steps.cfg.outputs.region }}
# Some all-demo deploys run past 1h; OIDC creds don't auto-refresh, so
# everything downstream — including teardown — fails NoCredentials.
# The role's max-session-duration must match (runbook step 10).
role-duration-seconds: 21600
- name: Configure GHCR pull credentials
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin || true
- name: SCP drift check
if: github.event_name == 'schedule'
env:
ACCOUNT_ID: ${{ steps.cfg.outputs.account_id }}
GITHUB_RUN_ID: ${{ github.run_id }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/smoke-scp-drift.sh
- name: Pre-deploy state check
id: predeploy
env:
STACK_NAME: ${{ env.STACK_NAME }}
GITHUB_RUN_ID: ${{ github.run_id }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/smoke-pre-deploy-state.sh
- name: Deploy all-demo (or scoped subset)
id: deploy
run: |
set -euo pipefail
STACK="${{ steps.predeploy.outputs.stack_name }}"
MODE="${{ needs.scope.outputs.mode }}"
# Tags must stay stable across runs. CFN propagates parent tags to
# nested stacks; any tag-change triggers a per-resource UPDATE, and
# AICC's AWS::Wisdom::* resources reject UPDATE (handler is
# CREATE/DELETE only) — that rolls the whole umbrella back. So no
# per-run tag values here; correlate runs via stack description.
aws cloudformation deploy \
--stack-name "$STACK" \
--template-file cloudformation/scenarios/all-demo/template.yaml \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND \
--parameter-overrides \
AiccExistingPhoneNumberArn='${{ steps.cfg.outputs.aicc_phone_arn }}' \
AiccExistingPhoneNumber='${{ steps.cfg.outputs.aicc_phone_number }}' \
--no-fail-on-empty-changeset \
--tags "Project=ndx-try" "SmokeMode=$MODE"
echo "stack_name=$STACK" >> "$GITHUB_OUTPUT"
- uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Quarantine-expiry check
run: node scripts/check-quarantines.mjs
- name: Run smoke pack
id: run
env:
SMOKE_STACK_NAME: ${{ steps.deploy.outputs.stack_name }}
SMOKE_AWS_REGION: ${{ steps.cfg.outputs.region }}
CI: 'true'
run: |
MODE="${{ needs.scope.outputs.mode }}"
if [ "$MODE" = "scoped" ]; then
PATTERN=$(echo '${{ needs.scope.outputs.scenarios }}' | jq -r 'join("|")')
./scripts/smoke.sh --grep "$PATTERN"
else
./scripts/smoke.sh
fi
# Captured BEFORE teardown so live-stack state survives failure.
- name: Capture CFN events
if: always() && steps.aws-creds.outcome == 'success'
env:
STACK: ${{ steps.deploy.outputs.stack_name || steps.predeploy.outputs.stack_name || env.STACK_NAME }}
run: ./scripts/smoke-capture-events.sh
- name: Upload artefact bundle
if: always()
uses: actions/upload-artifact@v7
with:
name: smoke-artefacts-${{ github.run_id }}
path: |
artefacts/
playwright-report/
test-results/
retention-days: 30
# Teardown only runs on the nightly cron. PR/push/dispatch runs always
# fix-forward against the persistent umbrella: a no-op `aws cloudformation
# deploy` on an unchanged template is a clean changeset-empty pass, so
# AICC's ConnectInstance, Wisdom resources, Lex bot, and SimplyReadable's
# logging bucket all stick around between runs (avoiding Connect quota
# exhaustion, Wisdom UPDATE-unsupported, Lex Creating-state delete-races,
# and CloudFront access-log bucket-not-empty races on teardown). The
# nightly cron still tears down so the account doesn't accumulate debris.
- name: Teardown
if: |
steps.aws-creds.outcome == 'success' &&
github.event_name == 'schedule'
env:
STACK: ${{ steps.deploy.outputs.stack_name || steps.predeploy.outputs.stack_name }}
GITHUB_RUN_ID: ${{ github.run_id }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/smoke-teardown.sh
- name: Open smoke-failed issue on cron failure
if: failure() && github.event_name == 'schedule'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue create --title "Nightly smoke failed (run ${{ github.run_id }})" \
--label smoke-failed \
--body "Smoke run ${{ github.run_id }} failed. Mode: ${{ needs.scope.outputs.mode }}. Artefacts: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/${{ github.run_id }}" || true