Schedule social media posts #2451
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Schedule social media posts | |
| on: | |
| # Fire after Build and deploy finishes on master so posts only go out | |
| # after the blog page is actually live. Posting on `push: master` raced | |
| # the deploy and produced 404 link cards (especially sticky on Bluesky, | |
| # which caches the first fetch of the og:image). | |
| workflow_run: | |
| workflows: ["Build and deploy"] | |
| types: [completed] | |
| branches: [master] | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Dry run — scan + show what would post, no posting / no state write" | |
| type: boolean | |
| default: false | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: schedule-social | |
| cancel-in-progress: false | |
| jobs: | |
| schedule-social: | |
| if: | | |
| github.repository == 'pulumi/docs' && | |
| (github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success') | |
| name: Schedule social media posts | |
| runs-on: ubuntu-latest | |
| environment: production | |
| env: | |
| FAILURE_SUMMARY_FILE: /tmp/social-failure-summary.txt | |
| outputs: | |
| failure_summary: ${{ steps.failure-summary.outputs.summary }} | |
| steps: | |
| - name: Fetch secrets from ESC | |
| id: esc-secrets | |
| uses: pulumi/esc-action@v3 | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| # On workflow_run, pin to the SHA the deploy actually built. Default | |
| # ref under workflow_run is master HEAD, which may have moved on. | |
| ref: ${{ github.event.workflow_run.head_sha || github.sha }} | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::388588623842:role/ContinuousDelivery | |
| role-session-name: social-scheduling | |
| aws-region: us-west-2 | |
| - uses: pulumi/actions@v7 | |
| - name: Get social state bucket name | |
| id: bucket | |
| env: | |
| PULUMI_ACCESS_TOKEN: ${{ steps.esc-secrets.outputs.PULUMI_ACCESS_TOKEN }} | |
| run: | | |
| set -eo pipefail | |
| BUCKET=$(pulumi -C infrastructure stack output socialStateBucketName --stack ${{ vars.PULUMI_STACK_NAME }}) | |
| echo "name=$BUCKET" >> "$GITHUB_OUTPUT" | |
| - uses: astral-sh/setup-uv@v7 | |
| - name: Configure git auth for private social_core git-dep | |
| env: | |
| PULUMI_BOT_TOKEN: ${{ steps.esc-secrets.outputs.PULUMI_BOT_TOKEN }} | |
| run: | | |
| git config --global url."https://x-access-token:${PULUMI_BOT_TOKEN}@github.com/".insteadOf "https://github.com/" | |
| - name: Validate upload-post.com API key | |
| env: | |
| UPLOAD_POST_API_KEY: ${{ steps.esc-secrets.outputs.UPLOAD_POST_API_KEY }} | |
| run: | | |
| if [ -z "$UPLOAD_POST_API_KEY" ]; then | |
| echo "::error::UPLOAD_POST_API_KEY is empty — check ESC environment" | |
| exit 1 | |
| fi | |
| STATUS=$(curl -s -o /tmp/api-check.txt -w "%{http_code}" \ | |
| -H @- \ | |
| "https://api.upload-post.com/api/uploadposts/history" \ | |
| <<< "Authorization: Apikey $UPLOAD_POST_API_KEY") | |
| if [ "$STATUS" != "200" ]; then | |
| echo "::error::upload-post.com API key validation failed (HTTP $STATUS)" | |
| cat /tmp/api-check.txt | |
| exit 1 | |
| fi | |
| echo "API key valid (HTTP 200)" | |
| - name: Schedule social posts for new blog content | |
| id: post | |
| continue-on-error: true | |
| env: | |
| UPLOAD_POST_API_KEY: ${{ steps.esc-secrets.outputs.UPLOAD_POST_API_KEY }} | |
| SOCIAL_STATE_BUCKET: ${{ steps.bucket.outputs.name }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| DRY_RUN: ${{ inputs.dry_run || 'false' }} | |
| run: uv run scripts/social/schedule-posts.py | |
| - name: Capture failure summary | |
| id: failure-summary | |
| if: steps.post.outcome == 'failure' | |
| run: | | |
| if [ -f "$FAILURE_SUMMARY_FILE" ]; then | |
| { | |
| echo "summary<<EOF" | |
| cat "$FAILURE_SUMMARY_FILE" | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Fail if posting step failed | |
| if: steps.post.outcome == 'failure' | |
| run: exit 1 | |
| notify: | |
| if: failure() && github.repository == 'pulumi/docs' | |
| name: Send slack notification | |
| runs-on: ubuntu-latest | |
| environment: production | |
| needs: [schedule-social] | |
| steps: | |
| - name: Fetch secrets from ESC | |
| id: esc-secrets | |
| uses: pulumi/esc-action@v3 | |
| - name: Slack Notification | |
| uses: docker://sholung/action-slack-notify:v2.3.0 | |
| env: | |
| SLACK_CHANNEL: docs-ops | |
| SLACK_COLOR: "#F54242" | |
| SLACK_MESSAGE: "social media scheduling failure in pulumi/docs repo :meow_sad: ${{ needs.schedule-social.outputs.failure_summary && format('({0}) ', needs.schedule-social.outputs.failure_summary) || '' }}${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| SLACK_USERNAME: docsbot | |
| SLACK_WEBHOOK: ${{ steps.esc-secrets.outputs.SLACK_WEBHOOK_URL }} | |
| SLACK_ICON: https://www.pulumi.com/logos/brand/avatar-on-white.png | |
| env: | |
| ESC_ACTION_OIDC_AUTH: true | |
| ESC_ACTION_OIDC_ORGANIZATION: pulumi | |
| ESC_ACTION_OIDC_REQUESTED_TOKEN_TYPE: urn:pulumi:token-type:access_token:organization | |
| ESC_ACTION_ENVIRONMENT: github-secrets/pulumi-docs | |
| ESC_ACTION_EXPORT_ENVIRONMENT_VARIABLES: false |