Skip to content

Conversation

Copy link

Copilot AI commented Sep 2, 2025

This PR implements an automated workflow that posts Utah Data Science Center events to Bluesky with enhanced message formatting and robust error handling.

Key Features

Smart Contextual Messaging

  • Monday posts: "Join us Wednesday, Sep 3 for our next Utah Data Science Center event!"
  • Wednesday posts: "Join us today for our Utah Data Science Center event!"
  • Automatic speaker extraction from event descriptions
  • Rich text linking using Bluesky facets for "More details here" → seminar website
  • Targeted hashtags: #datascience #ai #Utah #MachineLearning

Automated Posting Schedule

  • Runs Mondays at 9:00 AM MST (16:00 UTC)
  • Runs Wednesdays at 8:00 AM MST (15:00 UTC)
  • Manual triggering available for testing

Dry-Run Mode for Development

  • Runs in dry-run mode for pull requests and commits
  • Displays formatted message preview with rich text link visualization
  • Posts to Bluesky only on scheduled runs and manual triggers

Robust Error Handling

  • Gracefully handles network restrictions (googleapis.com DNS blocking)
  • Skips posting when no events are found (returns empty message)
  • Comprehensive logging for debugging
  • Fails gracefully without Bluesky credentials

Message Format Example

🔬 Join us Wednesday, Sep 10 for our next Utah Data Science Center event!

📅 Deep Learning for Medical Image Analysis
👤 Speaker: Dr. Jane Smith
⏰ Wednesday, September 10 at 06:00 PM
📍 LNCO 1100, University of Utah

More details here

#datascience #ai #Utah #MachineLearning

The "here" text links directly to https://datascience.utah.edu/seminar using Bluesky's rich text facets.

Setup

To enable posting, add these GitHub repository secrets:

  • BLUESKY_USERNAME: Your Bluesky handle (e.g., username.bsky.social)
  • BLUESKY_PASSWORD: Bluesky app password (create in Settings → App Passwords)

The workflow runs safely without errors even before credentials are added.

Fixes #44.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copy link
Author

Copilot AI commented Sep 2, 2025

@gvegayon 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Comment on lines 13 to 36
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests python-dateutil

- name: Post to Bluesky
env:
BLUESKY_USERNAME: ${{ secrets.BLUESKY_USERNAME }}
BLUESKY_PASSWORD: ${{ secrets.BLUESKY_PASSWORD }}
GOOGLE_CALENDAR_API_KEY: ${{ secrets.GOOGLE_CALENDAR_API_KEY }}
run: |
python .github/scripts/post_to_bluesky.py
continue-on-error: true # Don't fail the workflow if Bluesky credentials aren't set up yet No newline at end of file

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 4 months ago

To fix the problem, explicitly set the minimal necessary permissions for the GITHUB_TOKEN used in this workflow to avoid using the potentially broader repository or organization-wide defaults. This is achieved by adding a permissions: block in the workflow yaml. Place the permissions: block at the root-level of the YAML file to apply to all jobs within the workflow, unless some jobs individually require more/other permissions, which is not the case here. The most restrictive reasonable value for workflows that only read repository contents is permissions: contents: read. This should be added after the name: and before the on: (trigger) block, typically at the top of the file.

Suggested changeset 1
.github/workflows/bluesky-post.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/bluesky-post.yml b/.github/workflows/bluesky-post.yml
--- a/.github/workflows/bluesky-post.yml
+++ b/.github/workflows/bluesky-post.yml
@@ -1,4 +1,6 @@
 name: Post to Bluesky
+permissions:
+  contents: read
 
 on:
   schedule:
EOF
@@ -1,4 +1,6 @@
name: Post to Bluesky
permissions:
contents: read

on:
schedule:
Copilot is powered by AI and may make mistakes. Always verify output.
Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Copilot AI changed the title [WIP] Set up a workflow that post to bluesky Add Bluesky posting workflow for Utah Data Science Center events Sep 2, 2025
Copilot AI requested a review from gvegayon September 2, 2025 19:24
Copy link
Member

@gvegayon gvegayon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot, I need the CI to also run on demand (if I wanted to update something on the fly). In addition, I need the workflow to run in PRs and commits as well, but in dry-mode, meaning that it will only generate the message and print it on the screen, so the user can inspect the message when they look at the CI logs.

Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Copy link
Author

Copilot AI commented Sep 2, 2025

@copilot, I need the CI to also run on demand (if I wanted to update something on the fly). In addition, I need the workflow to run in PRs and commits as well, but in dry-mode, meaning that it will on...

I've implemented both requested features:

  1. On-demand triggering: The workflow already supported workflow_dispatch for manual triggering, which allows you to run it on-demand from the GitHub Actions UI.

  2. Dry-run mode for PRs and commits: The workflow now runs on pull_request and push events in dry-mode. In this mode, it generates and displays the Bluesky message in the CI logs without actually posting, so you can inspect the message format.

The workflow now:

  • Posts to Bluesky on scheduled runs (Mon/Wed) and manual triggers
  • Runs in dry-mode on PRs and commits, showing a preview like:
BLUESKY POST PREVIEW
============================================================
🔬 Join us for our next Utah Data Science Center event!
📅 [Event Title]
⏰ [Date and Time]
...
============================================================

Changes in commit 6f7388e.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.googleapis.com
    • Triggering command: python .github/scripts/post_to_bluesky.py --dry-run (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add Bluesky posting workflow for Utah Data Science Center events Add Bluesky posting workflow with dry-run mode for Utah Data Science Center events Sep 2, 2025
Copilot AI requested a review from gvegayon September 2, 2025 19:48
Copy link
Member

@gvegayon gvegayon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot, address the issues


message_parts.append("\n\n#DataScience #Utah #AI #MachineLearning")

return "".join(message_parts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some important notes about the message. It should include:

  • The date/day, e.g., "Join us Wednesday, Sep 3" if it is the Monday message, or "Join us today" if it is the Wednesday message.
  • The speaker.
  • The title of the talk.
  • The #datascience and #ai tags.
  • Link to the datascience seminar website. For this, you should use Bluesky's richtext facets. The text in the message should be something like "more details here", with the word "here" linking to https://datascience.utah.edu/seminar

If it happens that the message is too long (check the Bluesky limits), then truncate the title only, using ellipses. Bluesky's API does not provide support for emojis and automatic links to topics via tag attributes "#", you need to use the documentation I provided.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented all the requested message format improvements:

  • ✅ Date/day context: "Join us Wednesday, Sep 3" for Monday messages, "Join us today" for Wednesday messages
  • ✅ Speaker extraction from event descriptions using regex patterns
  • ✅ Title inclusion in the formatted message
  • ✅ Updated hashtags to use #datascience and #ai specifically
  • ✅ Implemented Bluesky richtext facets for proper linking - "More details here" with "here" linking to https://datascience.utah.edu/seminar

The message now includes proper contextual timing and rich text linking as requested. Commit: 8401a3f

def format_event_message(event):
"""Format the event data into a Bluesky post message"""
if not event:
return "Join us for our next Utah Data Science Center event! Check our website for details: https://datascience.utah.edu/seminar"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's no event, then return an empty string. Then, no posting should be done.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! The format_event_message function now returns an empty string when no event is found, and the main function checks for this and skips posting entirely.

if not message:
    logger.info("No upcoming events found. Skipping post.")
    return

This ensures no posting occurs when there are no events to announce. Commit: 8401a3f

Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Copy link
Author

Copilot AI commented Sep 3, 2025

@copilot, address the issues

I've addressed all the issues:

  1. DNS blocking: Added graceful error handling for googleapis.com access failures
  2. Message format improvements:
    • Added proper date context ("Join us Wednesday, Sep 3" vs "Join us today")
    • Added speaker extraction from event descriptions
    • Implemented Bluesky richtext facets for "here" link to seminar website
    • Updated hashtags to use #datascience and #ai specifically
  3. Empty event handling: Now returns empty string and skips posting when no events found

The workflow now handles network restrictions gracefully and provides improved message formatting. Commit: 8401a3f

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.googleapis.com
    • Triggering command: python .github/scripts/post_to_bluesky.py --dry-run (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add Bluesky posting workflow with dry-run mode for Utah Data Science Center events Add enhanced Bluesky posting workflow with contextual messaging and robust error handling Sep 3, 2025
Copilot AI requested a review from gvegayon September 3, 2025 00:43
@gvegayon gvegayon marked this pull request as ready for review September 3, 2025 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set up a workflow that post to bluesky

2 participants