name: Weekly Menu Scrape & Publish on: schedule: # Monday 7:30am EST = 12:30 UTC - cron: '30 12 * * 1' # Monday 7:30am EDT = 11:30 UTC - cron: '30 11 * * 1' workflow_dispatch: permissions: id-token: write contents: read jobs: scrape-and-publish: runs-on: ubuntu-latest env: AWS_REGION: us-east-1 steps: - name: Timezone guard if: github.event_name == 'schedule' run: | CRON="${{ github.event.schedule }}" OFFSET=$(TZ='America/New_York' date +%z) echo "Cron: $CRON | Eastern offset: $OFFSET" if { [ "$OFFSET" = "-0400" ] && [ "$CRON" = "30 12 * * 1" ]; } || \ { [ "$OFFSET" = "-0500" ] && [ "$CRON" = "30 11 * * 1" ]; }; then echo "Wrong-timezone cron fired — skipping" echo "SKIP_RUN=true" >> "$GITHUB_ENV" fi - uses: actions/checkout@v7 if: env.SKIP_RUN != 'true' - uses: actions/setup-python@v6 if: env.SKIP_RUN != 'true' with: python-version: '3.12' - name: Install dependencies if: env.SKIP_RUN != 'true' run: | pip install playwright boto3 playwright install chromium --with-deps - name: Configure AWS credentials if: env.SKIP_RUN != 'true' uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6 with: role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} aws-region: us-east-1 - name: Scrape menu if: env.SKIP_RUN != 'true' run: python3 src/scraper/scrape_menu.py - name: Get stack outputs if: env.SKIP_RUN != 'true' id: stack run: | API_URL=$(aws cloudformation describe-stacks \ --stack-name meal-order-manager \ --query 'Stacks[0].Outputs[?OutputKey==`ApiUrl`].OutputValue' \ --output text) FORM_BUCKET=$(aws cloudformation describe-stacks \ --stack-name meal-order-manager \ --query 'Stacks[0].Outputs[?OutputKey==`FormBucketName`].OutputValue' \ --output text) DIST_ID=$(aws cloudformation describe-stacks \ --stack-name meal-order-manager \ --query 'Stacks[0].Outputs[?OutputKey==`DistributionId`].OutputValue' \ --output text) FORM_URL=$(aws cloudformation describe-stacks \ --stack-name meal-order-manager \ --query 'Stacks[0].Outputs[?OutputKey==`FormUrl`].OutputValue' \ --output text) echo "api_url=$API_URL" >> $GITHUB_OUTPUT echo "form_bucket=$FORM_BUCKET" >> $GITHUB_OUTPUT echo "dist_id=$DIST_ID" >> $GITHUB_OUTPUT echo "form_url=$FORM_URL" >> $GITHUB_OUTPUT - name: Get API key if: env.SKIP_RUN != 'true' id: apikey run: | API_KEY=$(aws secretsmanager get-secret-value \ --secret-id meal-order-manager/form-api-key \ --query 'SecretString' --output text) echo "::add-mask::$API_KEY" echo "api_key=$API_KEY" >> $GITHUB_OUTPUT - name: Get discount settings if: env.SKIP_RUN != 'true' id: discount run: | RESULT=$(aws dynamodb get-item \ --table-name meal-order-manager-orders \ --key '{"PK":{"S":"CONFIG"},"SK":{"S":"SETTINGS"}}' \ --output json 2>/dev/null || echo '{}') BULK=$(echo "$RESULT" | python3 -c " import sys, json d = json.load(sys.stdin) print(d.get('Item',{}).get('bulk_discount_percent',{}).get('N','0')) " 2>/dev/null || echo "0") SUBSIDY=$(echo "$RESULT" | python3 -c " import sys, json d = json.load(sys.stdin) print(d.get('Item',{}).get('company_subsidy_percent',{}).get('N','0')) " 2>/dev/null || echo "0") echo "bulk_discount=$BULK" >> $GITHUB_OUTPUT echo "company_subsidy=$SUBSIDY" >> $GITHUB_OUTPUT - name: Get Google Client ID if: env.SKIP_RUN != 'true' id: google run: | GOOGLE_CLIENT_ID=$(aws ssm get-parameter \ --name /meal-order-manager/google-client-id \ --query 'Parameter.Value' \ --output text 2>/dev/null || echo "") if [ "$GOOGLE_CLIENT_ID" = "None" ] || [ -z "$GOOGLE_CLIENT_ID" ]; then GOOGLE_CLIENT_ID="" fi echo "client_id=$GOOGLE_CLIENT_ID" >> $GITHUB_OUTPUT - name: Generate order form if: env.SKIP_RUN != 'true' run: | python3 src/server/generate_form.py \ --api-url "${{ steps.stack.outputs.api_url }}" \ --api-key "${{ steps.apikey.outputs.api_key }}" \ --bulk-discount "${{ steps.discount.outputs.bulk_discount }}" \ --company-subsidy "${{ steps.discount.outputs.company_subsidy }}" \ ${{ steps.google.outputs.client_id && format('--google-client-id "{0}"', steps.google.outputs.client_id) || '' }} - name: Upload menu to DynamoDB if: env.SKIP_RUN != 'true' run: python3 scripts/upload_menu.py - name: Upload form to S3 if: env.SKIP_RUN != 'true' run: | WEEK=$(date +%Y-W%U) aws s3 cp "output/order-form-$WEEK.html" \ "s3://${{ steps.stack.outputs.form_bucket }}/index.html" \ --content-type "text/html" \ --cache-control "no-cache" aws s3 cp "output/order-form-$WEEK.html" \ "s3://${{ steps.stack.outputs.form_bucket }}/archive/$WEEK.html" \ --content-type "text/html" - name: Invalidate CloudFront cache if: env.SKIP_RUN != 'true' run: | aws cloudfront create-invalidation \ --distribution-id "${{ steps.stack.outputs.dist_id }}" \ --paths "/index.html" - name: Notify Slack if: env.SKIP_RUN != 'true' run: python3 scripts/notify_slack.py "${{ steps.stack.outputs.form_url }}"