name: Daily Version Bump on: schedule: # 6pm ET (EDT = 22:00 UTC, EST = 23:00 UTC) - cron: "0 22 * * *" - cron: "0 23 * * *" workflow_dispatch: {} permissions: contents: write jobs: notify: runs-on: ubuntu-latest env: GH_TOKEN: ${{ github.token }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true - name: DST guard id: dst run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then echo "Manual trigger — skipping DST guard" echo "skip=false" >> "$GITHUB_OUTPUT" exit 0 fi HOUR=$(TZ=America/New_York date +%H) if [ "$HOUR" != "18" ]; then echo "ET hour is $HOUR, not 18 — wrong DST rule fired" echo "skip=true" >> "$GITHUB_OUTPUT" else echo "skip=false" >> "$GITHUB_OUTPUT" fi - name: Collect merged PRs since last version if: steps.dst.outputs.skip != 'true' id: changes run: | LAST_TAG=$(git tag -l 'v*' --sort=-v:refname | head -1) if [ -z "$LAST_TAG" ]; then echo "No previous version tag" echo "has_changes=false" >> "$GITHUB_OUTPUT" exit 0 fi LAST_TAG_DATE=$(git log -1 --format=%aI "$LAST_TAG") PRS=$(gh pr list --state merged --json number,title,mergedAt \ --jq "sort_by(.number) | .[] | select(.mergedAt > \"$LAST_TAG_DATE\")") if [ -z "$PRS" ]; then echo "No PRs merged since $LAST_TAG" echo "has_changes=false" >> "$GITHUB_OUTPUT" exit 0 fi echo "has_changes=true" >> "$GITHUB_OUTPUT" VERSION="v$(TZ=America/New_York date +%Y.%m.%d)" echo "version=$VERSION" >> "$GITHUB_OUTPUT" # Build bullet lists from PR titles TITLES=$(gh pr list --state merged --json number,title,mergedAt \ --jq "sort_by(.number) | .[] | select(.mergedAt > \"$LAST_TAG_DATE\") | .title") { echo "slack_bullets<> "$GITHUB_OUTPUT" { echo "canvas_bullets< \"$LAST_TAG_DATE\") | \"* \(.title) (PR #\(.number))\"" \ | sed 's/ *(\(#[0-9]*\))\( (PR\)/ \2/; s/) (PR / (PR /' echo "ENDCANVAS" } >> "$GITHUB_OUTPUT" - name: Create version tag if: steps.changes.outputs.has_changes == 'true' run: | git tag ${{ steps.changes.outputs.version }} git push origin ${{ steps.changes.outputs.version }} - name: Update changelog canvas if: steps.changes.outputs.has_changes == 'true' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} CANVAS_ID: ${{ secrets.SLACK_CANVAS_ID }} SECTION_ID: ${{ secrets.SLACK_CANVAS_INTRO_SECTION }} VERSION: ${{ steps.changes.outputs.version }} CANVAS_BULLETS: ${{ steps.changes.outputs.canvas_bullets }} run: | TODAY=$(TZ=America/New_York date +%Y-%m-%d) MARKDOWN=$(printf "---\n\n## %s — %s\n\n%s" "$VERSION" "$TODAY" "$CANVAS_BULLETS") RESPONSE=$(curl -s -X POST https://slack.com/api/canvases.edit \ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg canvas_id "$CANVAS_ID" \ --arg section_id "$SECTION_ID" \ --arg markdown "$MARKDOWN" \ '{ canvas_id: $canvas_id, changes: [{ operation: "insert_after", section_id: $section_id, document_content: { type: "markdown", markdown: $markdown } }] }')") echo "$RESPONSE" | jq . if [ "$(echo "$RESPONSE" | jq -r .ok)" != "true" ]; then echo "::warning::Canvas update failed: $(echo "$RESPONSE" | jq -r .error)" fi - name: Post to Slack if: steps.changes.outputs.has_changes == 'true' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} CANVAS_ID: ${{ secrets.SLACK_CANVAS_ID }} VERSION: ${{ steps.changes.outputs.version }} SLACK_BULLETS: ${{ steps.changes.outputs.slack_bullets }} run: | CANVAS_URL="https://app.slack.com/docs/F0B13V3EBUN" TEXT=$(printf "*After-Hours Scheduler has been updated to %s*\n\nHere's a brief summary of what changed:\n%s\n\n<%s|Click here to read the full changelog>" \ "$VERSION" "$SLACK_BULLETS" "$CANVAS_URL") curl -s -X POST https://slack.com/api/chat.postMessage \ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg channel "$SLACK_CHANNEL_ID" --arg text "$TEXT" \ '{channel: $channel, text: $text}')"