Skip to content

Add workflow to publish release notes directly to discourse #7860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ricardoV94
Copy link
Member

@ricardoV94 ricardoV94 commented Jul 21, 2025


📚 Documentation preview 📚: https://pymc--7860.org.readthedocs.build/en/7860/

DISCOURSE_URL: "https://discourse.pymc.io"
DISCOURSE_CATEGORY: "Development"
RELEASE_TAG: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body }}
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure if I need to escape to json or not

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds automation to publish GitHub release notes directly to a Discourse forum. The implementation includes a Python script that fetches release information from GitHub and posts it as a formatted topic to Discourse using their API.

Key changes:

  • Python script for publishing release notes to Discourse with error handling and content formatting
  • GitHub Actions workflow triggered on release publication
  • Configuration updates to allow print statements in the script

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
scripts/publish_release_notes_to_discourse.py Main script that handles Discourse API communication and content formatting
.github/workflows/publish-release-notes-to-discourse.yml GitHub Actions workflow to trigger the script on release events
pyproject.toml Linting configuration update to allow print statements in the new script

url = f"{config['DISCOURSE_URL']}/posts.json"

try:
response = requests.post(url, headers=headers, data=topic_data)
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

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

The request should use 'json=topic_data' instead of 'data=topic_data' since the headers specify 'Content-Type: application/json' but this parameter sends form-encoded data.

Suggested change
response = requests.post(url, headers=headers, data=topic_data)
response = requests.post(url, headers=headers, json=topic_data)

Copilot uses AI. Check for mistakes.

Copy link
Member Author

@ricardoV94 ricardoV94 Jul 21, 2025

Choose a reason for hiding this comment

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

data seemed to work fine, but this is something I'm still not sure about, also on how to pass from the workflow to script. Rather test and see how it goes

Comment on lines 100 to 108
headers = {"Api-Key": config["DISCOURSE_API_KEY"], "Api-Username": config["DISCOURSE_USERNAME"]}
url = f"{config['DISCOURSE_URL']}/posts.json"

try:
response = requests.post(url, headers=headers, data=topic_data)
Copy link
Preview

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

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

The headers for the POST request are missing 'Content-Type: application/json' which is included in the GET request headers and is necessary when sending JSON data.

Suggested change
headers = {"Api-Key": config["DISCOURSE_API_KEY"], "Api-Username": config["DISCOURSE_USERNAME"]}
url = f"{config['DISCOURSE_URL']}/posts.json"
try:
response = requests.post(url, headers=headers, data=topic_data)
headers = {
"Api-Key": config["DISCOURSE_API_KEY"],
"Api-Username": config["DISCOURSE_USERNAME"],
"Content-Type": "application/json",
}
url = f"{config['DISCOURSE_URL']}/posts.json"
try:
response = requests.post(url, headers=headers, json=topic_data)

Copilot uses AI. Check for mistakes.

@ricardoV94 ricardoV94 force-pushed the publish-release-notes-to-discourse branch from 31727a9 to d56efbe Compare July 21, 2025 12:22
Comment on lines +8 to +34
publish-to-discourse:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false

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

- name: Install dependencies
run: pip install requests

- name: Publish release to Discourse
env:
DISCOURSE_API_KEY: ${{ secrets.DISCOURSE_API_KEY }}
DISCOURSE_USERNAME: "pymc-bot"
DISCOURSE_URL: "https://discourse.pymc.io"
DISCOURSE_CATEGORY: "Development"
RELEASE_TAG: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body }}
RELEASE_URL: ${{ github.event.release.html_url }}
REPO_NAME: ${{ github.repository }}

Check warning

Code scanning / zizmor

overly broad permissions Warning

overly broad permissions
@ricardoV94
Copy link
Member Author

ricardoV94 commented Jul 22, 2025

I suggest we merge and the next release will confirm whether the release.body output is formatting correctly or not, that's my only doubt, and I don't know a way to test locally. I've tested locally the rest.

@ricardoV94 ricardoV94 requested review from maresb and twiecki July 22, 2025 16:58
@ricardoV94 ricardoV94 merged commit 5f611b5 into pymc-devs:main Jul 22, 2025
13 checks passed
@maresb
Copy link
Contributor

maresb commented Jul 24, 2025

I'm a bit late to the review party, but ideally we should scope secrets.DISCOURSE_API_KEY to the release environment. This would dramatically reduce the attack surface for a GitHub actor to steal the API key.

It's really simple and low-effort:

  • Remove the API key from "repository secrets"
  • Readd the key to "environment secrets" under the "release" environment
  • Add the "release" environment to this publish-to-discourse job, copying the line from the above link into this workflow.

I don't have admin permissions on the PyMC repo to set this up myself.

@ricardoV94
Copy link
Member Author

Ok I'll try it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants