A GitHub Action to schedule the posting of Discussion Posts at a future date and time
MIT License
This action will create a discussion post in a repository at a scheduled time.
Setting up the action requires three steps (described in detail below):
The Action is intended to be used with two or more repositories:
Draft discussion posts live as .md
files in the root of the source repository.
When the action runs (on a regular basis), it will look for any draft posts that
are scheduled to be published (publication date in the past) and will create a
coresponding discussion post in the target repository. You can schedule as many
draft discussion posts as you'd like. Once published, the draft post will be
deleted. to keep things tidy in the source repository.
Create a .github/workflows/schedule-discussion-post.yml
file in your
repository with the following content:
name: Schedule Discussion Posts
on:
# Check for drafts to post every hour at the top of the hour
schedule:
- cron: '0 * * * *'
# Optional, allows you to post on demand
push:
branches:
- 'main'
paths:
- '**.md'
permissions:
contents: write
jobs:
schedule-discussion-posts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: benbalter/schedule-discussion-posts-action@main
with:
discussion_token: ${{ secrets.DISCUSSION_TOKEN }}
This will run approximately on the top of the hour, every hour to check for
posts to pubish. You can use tools like crontab.guru
to adjust the schedule to
your liking.
Pro-tip: If this is a new repository, be sure to enable Discussions via the settings.
For the Action to work, the intended author will need to create a Personal Access Token:
github.com/settings/tokens
.DISCUSSION_TOKEN
) in the repository where youNote: You can optionally create a legacy PAT which would not have an expiration date, but that would grant discussion read/write access to all repositories that the author has access to.
Pro-tip: Set a calendar reminder to roll the token prior to the expiration date.
Discussion posts start as .md
files in the root of the repository where you
set up the Action (the source repository). You can schedule as many posts as
you'd like. Posts are standard Markdown files, with a few extra "front matter"
fields at the top. Here's an example:
---
title: An important post
date: 2021-10-01T12:00:00Z
repository: github/schedule-discussion-post-action
category: General
labels: announcement, engineering
---
Body of the post here in standard Markdown.
Note: You do not (and should not) include the title in the body of the draft as an H1. Instead, add it to the front matter so that it can be set appropriately.
The following front matter fields are supported:
title
(required): The title of the discussion postdate
(required): The date and time to post the discussion post. The Actionrepository
(required): The target repository where the discussion post willowner/repository
.category
(required): The category of the discussion post.labels
(optional): A comma-separated list of labels to apply to theauthor
(optional): The GitHub handle of the author of the post. Defaults toDISCUSSION_TOKEN
.Note: Setting labels is not yet implemented due to restrictions with the GitHub API.
For additional peace of mind, you can set up a "linter" to check your drafts.
Create a .github/workflows/lint-drafts.yml
file in your source repository with
the following content:
name: Lint drafts
on:
pull_request:
branches:
- main
permissions:
contents: read
jobs:
changed_files:
runs-on: ubuntu-latest
name: Test changed-files
steps:
- uses: actions/checkout@v4
- name: Get all changed markdown files
id: changed-markdown-files
uses: tj-actions/changed-files@v44
with:
json: true
escape_json: false
files: |
**.md
- name: Lint markdown files
uses: benbalter/schedule-discussion-posts-action@main
if: steps.changed-markdown-files.outputs.any_changed == 'true'
with:
dry_run: true
files: ${{ steps.changed-markdown-files.outputs.all_changed_files }}
discussion_token: ${{ secrets.DISCUSSION_TOKEN }}
This will run through the entire process of parsing and validating any changed draft in a pull request, but stop shot of actually creating the discussion post. If there are any issues, the Action will fail and provide feedback on what needs to be fixed. This should catch most issues giving you confidence that the post will be created as expected.
Note: This Workflow file assumes you're using a pull request workflow. If you're
not, adjust the on
trigger accordingly (example: on push to main
).
Example Lint output:
The Action accepts the following with:
parameters:
discussion_token
(required): The Personal Access Token to use to create therepo_token
(optional): The Personal Access Token to use to read the draftgithub.token
provided by the GitHub Actions runtime.dry_run
(optional): If set to true
, the Action will parse the draftfalse
.files
(optional): A JSON-formatted array of files to parse. Defaults to all.md
files in the repository root.By default, the action will use the DISCUSSION_TOKEN
secret to create the
discussion post (which will be authored by the user who created the token). If
you want to specify a different author, you can add an author
field to the
front matter of the draft post with their handle. For example:
---
title: Another important post, authored by someone else
date: 2021-10-01T12:00:00Z
repositotry: github/schedule-discussion-post-action
category: General
author: hubot
---
You will then need to follow the instructions above to create a Personal Access
Token for that user and add it to the repository secrets as
DISCUSSION_TOKEN_$HANDLE
(in this case, DISCUSSION_TOKEN_HUBOT
).
Finally, you will need to update the Action configuration to pass the additional token. For example:
jobs:
schedule-discussion-posts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: benbalter/schedule-discussion-posts-action@main
with:
# The default token used when no author is specified
discussion_token: ${{ secrets.DISCUSSION_TOKEN }}
# The token to use when the author is hubot
discussion_token_hubot: ${{ secrets.DISCUSSION_TOKEN_HUBOT }}
You may add as many authors to a repository as you'd like, each with their own token. The Action will use the appropriate token based on the author specified in the draft post. If the author specified does not have a corresponding token, the Action will try to use the default token, but will warn you that the author is not set up correctly when you do a dry run.
Note: If the author's handle has -
in it, replace the -
with _
when naming
the secret as GitHub Actions does not allow -
s in secret names.
If you encounter any issues, please check the following: