See https://til.simonwillison.net/github-actions/daily-planner
December 22, 2023 at 8:27:27 AM
[ Part of this conversation removed ]
Prompt:
Give me the GitHub YAML to create an issue template for my daily planner - should have an area for priorities and a list of todos
ChatGPT:
To create a GitHub issue template for your daily planner, you can use the following YAML configuration. This template will include sections for setting priorities and listing to-dos:
name: Daily Planner Issue
description: Template for daily planning.
title: "[Date] - Daily Plan"
labels: ["daily-planner", "todo"]
assignees: ["your-username"]
body:
- type: markdown
attributes:
value: "## Daily Planner for [Insert Date Here]"
- type: textarea
attributes:
label: "Date"
description: "Enter the date for this plan."
placeholder: "YYYY-MM-DD"
render: "YYYY-MM-DD"
- type: textarea
attributes:
label: "Priorities"
description: "List your top priorities for the day."
placeholder: "1. Priority One\n2. Priority Two\n3. Priority Three"
- type: textarea
attributes:
label: "To-Do List"
description: "List all tasks that you need to complete today."
placeholder: "- [ ] Task 1\n- [ ] Task 2\n- [ ] Task 3"
To use this template:
- Create a new file in your repository under
.github/ISSUE_TEMPLATE/
nameddaily-planner.yml
. - Copy the YAML content provided above into this file.
- Edit the
assignees
field to include your GitHub username or the username of whoever is responsible for managing the daily planner issues. - Adjust any other fields as needed to fit your specific planning process.
Once this file is committed to your repository, you will be able to use this template for creating new issues for daily planning. Each issue created with this template will have sections for the date, priorities, and a to-do list.
Prompt:
Can I construct a URL that pre fills the title of a GitHub issue?
ChatGPT:
Yes, you can construct a URL to pre-fill the title of a GitHub issue. GitHub provides query parameters that you can add to the URL of the issue creation page to pre-fill various fields, including the title. Here's how you can do it:
-
Start with the base URL for creating a new issue in your repository. It looks like this:
https://github.com/[username]/[repository]/issues/new
Replace
[username]
with your GitHub username and[repository]
with the name of your repository. -
Add a query parameter to pre-fill the title. Append
?title=
to the URL followed by the title you want to pre-fill. Make sure to encode any spaces or special characters.
For example, to pre-fill the title with "Daily Plan for 2023-12-22", your URL would be:
https://github.com/username/repository/issues/new?title=Daily+Plan+for+2023-12-22
Remember to replace username
, repository
, and the title as per your requirements. When someone visits this URL, they'll be taken to the new issue page on your repository with the title already filled in.
Prompt:
Write a GitHub Actions workflow which retrieves a list of issue names and URLs for the current repo, converts those into a JSON array and then publishes that as issue-titles.json using GitHub Pages
ChatGPT:
To create a GitHub Actions workflow that retrieves a list of issue titles and URLs for the current repository, converts them into a JSON array, and publishes the result as issue-titles.json
using GitHub Pages, you'll need to follow these steps:
-
Create the Workflow File: In your GitHub repository, create a file in the
.github/workflows
directory. You might name itissues-to-json.yml
. -
Workflow Content: The workflow will use GitHub's REST API to fetch the issues, format them into JSON, and then commit the file to a branch (typically
gh-pages
) that GitHub Pages uses to serve the content.
Here's an example of how the workflow file (issues-to-json.yml
) might look:
name: Generate Issues JSON
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Runs every day at midnight
jobs:
generate-json:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Fetch Issues
id: get-issues
uses: actions/github-script@v5
with:
script: |
const response = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
return response.data.map(issue => ({ title: issue.title, url: issue.html_url }));
- name: Write JSON File
run: echo '${{ toJSON(steps.get-issues.outputs.result) }}' > issue-titles.json
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./
publish_branch: gh-pages # The branch GitHub Pages uses
keep_files: true
This workflow does the following:
- It is triggered manually (
workflow_dispatch
) or on a schedule (midnight daily in this example). - It fetches open issues from the repository.
- Converts the issue data to JSON and writes it to
issue-titles.json
. - Deploys the file to the
gh-pages
branch usingpeaceiris/actions-gh-pages
action.
-
Configure GitHub Pages: In your repository's settings, configure GitHub Pages to serve files from the
gh-pages
branch. -
Access the JSON File: Once the workflow has run, you can access the JSON file at
https://<username>.github.io/<repository>/issue-titles.json
.
Remember to replace <username>
and <repository>
with your GitHub username and repository name, respectively. Also, ensure that the GitHub Pages feature is enabled for your repository.
Prompt:
I want it to trigger on issue creation as well
ChatGPT:
To modify the GitHub Actions workflow so that it triggers on issue creation as well, you can add the issues
event with the opened
activity type to the on
section of your workflow file. This will cause the workflow to run not only on a schedule and when manually triggered, but also every time a new issue is created in your repository.
Here's the updated workflow (issues-to-json.yml
):
name: Generate Issues JSON
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Runs every day at midnight
issues:
types: [opened]
jobs:
generate-json:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Fetch Issues
id: get-issues
uses: actions/github-script@v5
with:
script: |
const response = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
return response.data.map(issue => ({ title: issue.title, url: issue.html_url }));
- name: Write JSON File
run: echo '${{ toJSON(steps.get-issues.outputs.result) }}' > issue-titles.json
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./
publish_branch: gh-pages # The branch GitHub Pages uses
keep_files: true
With this configuration, the workflow will be triggered whenever:
- A new issue is created (
issues: types: [opened]
). - The workflow is manually triggered (
workflow_dispatch
). - The scheduled time is reached (every day at midnight in the
cron
schedule).
This ensures your issue-titles.json
file in the GitHub Pages branch is updated not only on a daily schedule but also immediately when a new issue is created.
Prompt:
Make it have one step that uses GitHub-script and writes the file to disk
ChatGPT:
To streamline the GitHub Actions workflow into a single step that uses actions/github-script
and directly writes the JSON file to disk, you can combine the fetching of issues and the file creation into one script. This makes the workflow more efficient by reducing the number of steps. Here's how the updated workflow (issues-to-json.yml
) will look:
name: Generate Issues JSON
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Runs every day at midnight
issues:
types: [opened]
jobs:
generate-json:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Fetch Issues and Write JSON
uses: actions/github-script@v5
with:
script: |
const fs = require('fs');
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
const issueData = issues.data.map(issue => ({ title: issue.title, url: issue.html_url }));
fs.writeFileSync('issue-titles.json', JSON.stringify(issueData, null, 2));
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./
publish_branch: gh-pages # The branch GitHub Pages uses
keep_files: true
In this version:
- The
Fetch Issues and Write JSON
step usesactions/github-script
to fetch the issues and then uses Node.js'sfs
module to write the data toissue-titles.json
directly. - The file is then deployed to the
gh-pages
branch with thepeaceiris/actions-gh-pages
action.
This single-step approach for script execution is more concise and maintains the efficiency of the workflow.
Prompt:
Write an index.html file which runs JavaScript that does the following:
Generate a string for today's date like this: 2023-12-22 Friday 22nd December
Fetch issue-titles.json using fetch()
The format of that will be:
[ { "title": "2023-12-22 Friday 22nd December", "url": "https://github.com/simonw/planner/issues/1" } ]
If the calculated title is already there, redirect the user to that url
Otherwise, send the user to this page:
https://github.com/simonw/planner/issues/new?template=day.yml&title=
Fill in the title with the URL a encoded title
ChatGPT:
To achieve the functionality you've described, we can create an index.html
file that contains JavaScript code to generate today's date, fetch issue-titles.json
, and perform the necessary redirection based on the issue titles. The JavaScript will also handle URL encoding for the title when redirecting to the new issue page. Here's how the index.html
file would look:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Daily Planner Issue Redirector</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
const date = new Date();
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const dateString = date.toLocaleDateString('en-US', options);
const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${dateString}`;
fetch('issue-titles.json')
.then(response => response.json())
.then(issues => {
const matchingIssue = issues.find(issue => issue.title === formattedDate);
if (matchingIssue) {
window.location.href = matchingIssue.url;
} else {
const encodedTitle = encodeURIComponent(formattedDate);
window.location.href = `https://github.com/simonw/planner/issues/new?template=day.yml&title=${encodedTitle}`;
}
})
.catch(error => console.error('Error fetching issue titles:', error));
});
</script>
</head>
<body>
<h1>Redirecting...</h1>
</body>
</html>
This HTML file does the following:
-
Date Generation: It creates a formatted date string in the format "YYYY-MM-DD Day DDth Month".
-
Fetch
issue-titles.json
: Usesfetch()
to retrieve the JSON file containing issue titles and URLs. -
Check for Existing Issue: Searches the JSON data for an issue with a title matching today's date.
-
Redirect Logic:
- If an issue with today's date is found, redirects the user to that issue's URL.
- If no matching issue is found, redirects the user to the new issue page with the title pre-filled (URL-encoded).
-
Error Handling: Logs any errors that occur during the fetch operation.
Make sure your server is correctly configured to serve issue-titles.json
, and that CORS policies allow for fetching this file. Also, replace the repository URL https://github.com/simonw/planner/issues/new
with the actual URL of your repository.
Prompt:
Modify the JavaScript to only consider yyyy-mm-dd and to return a match if any of the dates start with that substring
system:
ChatGPT:
To modify the JavaScript so that it only considers the "yyyy-mm-dd" part of the date and returns a match if any of the issue titles start with that substring, you can adjust the script to compare only the beginning of the title strings with the formatted date. Here's the updated JavaScript within the index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Daily Planner Issue Redirector</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
const today = new Date();
const formattedToday = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
fetch('issue-titles.json')
.then(response => response.json())
.then(issues => {
const matchingIssue = issues.find(issue => issue.title.startsWith(formattedToday));
if (matchingIssue) {
window.location.href = matchingIssue.url;
} else {
const fullDateOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const fullDateString = today.toLocaleDateString('en-US', fullDateOptions);
const title = `${formattedToday} ${fullDateString}`;
const encodedTitle = encodeURIComponent(title);
window.location.href = `https://github.com/simonw/planner/issues/new?template=day.yml&title=${encodedTitle}`;
}
})
.catch(error => console.error('Error fetching issue titles:', error));
});
</script>
</head>
<body>
<h1>Redirecting...</h1>
</body>
</html>
Changes made:
-
Formatted Date: The
formattedToday
variable now holds only the "yyyy-mm-dd" part of the date. -
Issue Matching: The
matchingIssue
variable is determined by checking if any issue title starts with theformattedToday
string. -
Full Date String for New Issue: If no match is found, a full date string is generated for the new issue's title.
-
Redirection: The redirection logic remains the same, but now it uses the new criteria for finding a matching issue.
This updated script ensures that the check for existing issues is based only on the "yyyy-mm-dd" portion of the issue titles, which aligns with your requirements.