wgutils
v2.1.3
Published
Tools for managing working groups
Readme
wgutils
This is a utility command to help with managing Working Groups. It was designed for the GraphQL Working Groups, but could be used for other projects that work in a similar way (if this is of interest, get in touch and we can figure out how to make it even more configurable).
Installation
yarn add wgutilswgutils init
Create an example wg.config.js file with the wgutils init command:
wgutils initThen edit this file and customize it for the local repository.
wg.config.js
Main options:
name- name of the WG, e.g."GraphQL WG"repoUrl- the root URL to the repo, e.g."https://github.com/graphql/graphql-wg"meetings(optional) - set tofalsefor repositories that do not manage meetings, such as spec-only repositoriesspec(optional) - required for spec publishing/versioning commands:title- the name of the specification, excluding the word "Specification". E.g. "GraphQL" or "GraphQL over HTTP"url- the root URL to the specification; appending/draft/should view the draft versionmainFile- the file that gets fed intospec-md, e.g.spec/GraphQL.md
Meeting options, required unless meetings: false is set:
videoConferenceDetails- the video conference URL; gets interpolated into the markdown, so if additional details (e.g. password) are required include them indented after a newlineliveNotesUrl- the URL to the Google Doc that is used for the live notesattendeesTemplate- a markdown table for your attendees to populatetimezone-US/PacificorUTCor similar; what time governs your meeting times. Critical for international daylight savings time.frequency-monthlyorweekly- how frequently do you meetweekday-M,Tu,W,Th,F,SaorSu- which day of the week do you meet on?time- the time range of the meeting in strict 24 hour range format:HH:MM-HH:MM(e.g.12:30-14:00)
When frequency = 'monthly':
nth- 1-4 - which of theweekdaysdo you meet on?secondaryMeetings- are there additional meetings? If so, a list of them:nth- which instancedayOffset(optional) - if this meeting is a different day of the week, how does it relate to the normal schedule? (e.g. if you normally meet Thursdays, then Wednesday would be-1)time- the time range of the meeting in strict 24 hour range format:HH:MM-HH:MM(e.g.12:30-14:00)name(optional) - a name for this secondary meetingdescription(optional) - a description for this secondary meetingfilenameFragment(optional) - extra text to add to the agenda filename
When frequency = 'weekly':
primaryN- which meeting is the primary (if any)? We really only support this being1right now...
Optional but important options:
joiningAMeetingFile(optional) - if your repository contains a "JoiningAMeeting.md" file, name it here and we'll embed parts into the agendasdescription(optional) - description of the working group; will appear in agendasdateAndTimeLocations(optional) - the locations to add to the end of thedateandtime.comURL for the time of the meetingfilenameFragment(optional) - extra text to add to the agenda filename
Options that are unlikely to be overridden for new projects:
links(optional) - an object defining some named links to use in the markdown (e.g. from thedescription)repoSubpath(optional) - if theagendas/etc folder is not in the root, the relative path to it. Unlikely you'll need this.agendasFolder(optional) - the name of the folder the agendas are stored in (i.e."agendas"), relative torepoSubpath(or the repo root)
For a repository that only manages a specification and does not manage meetings, the configuration can omit all meeting options:
// @ts-check
/** @type {import('wgutils').Config} */
const config = {
name: "GraphQL Specification",
repoUrl: "https://github.com/graphql/graphql-spec",
meetings: false,
spec: {
title: "GraphQL",
url: "https://spec.graphql.org",
mainFile: "spec/GraphQL.md",
},
};
module.exports = config;wgutils agenda gen
Generates agenda files for the given year and month, according to the settings
in wg.config.js.
Example: generate the agenda file(s) for April 2024:
wgutils agenda gen 2024 4wgutils spec build
Build the spec into the public/ folder.
wgutils spec version
Generates a changelog for a new specification version in changelogs/<tag>.md.
This command requires spec.title, spec.url and spec.mainFile in
wg.config.js (use with meetings: false for spec-only repos).
Example: generate the September2026 spec changelog:
wgutils spec version September2026Use --current to compare against a commit other than HEAD. Use --previous
MonthYYYY (or --no-previous) to override the autodetected previous tag. Use
--force to allow an unexpected tag name (e.g. out of date) and/or overwrite an
existing changelog. Use --debug for verbose logging. These together are useful
for validating the script output from previous version runs.
wgutils spec version --previous October2021 --current f29fbcd2ab5af763fce7ad62896eb62465a669b3 September2025 --force --debugwgutils spec release
Release the result of a previous wgutils spec version command by:
- Checking the spec title is correct.
- Fixing references in the changelog.
- Creating an annotated git tag for the current release.
- Changing the spec title back to "Current Working Draft".
The tag must match the previous wgutils spec version run and this command must
run on main after the draft release has been merged.
wgutils can-automerge
First, and SUPER IMPORTANT, make sure that your main branch is configured
with branch protections, and that EasyCLA is listed in the list of required
checks to pass.
Then you can add it to your repo with a GitHub action such as:
name: Agenda auto-merge
on:
pull_request_target:
types: [synchronize, opened, reopened]
permissions:
contents: write
pull-requests: read
checks: read
jobs:
validate-and-merge:
if: ${{ github.event.pull_request.base.ref == 'main' }}
runs-on: ubuntu-latest
steps:
# SECURITY: it's critical we do not check out the source pull request!
- name: Checkout the main branch
uses: actions/checkout@v3
with:
ref: main
# We need wgutils to be installed
- run: yarn install
- name: Wait for checks to pass
env:
GH_TOKEN: ${{ github.token }}
run: |
# Give 15 seconds for any checks to register
sleep 15
# Wait for checks to pass
gh pr checks ${{ github.event.pull_request.number }} --fail-fast --watch --required 2>&1 || true
# Now get the result in JSON
CHECKS_OUTPUT="$(gh pr checks ${{ github.event.pull_request.number }} --required --json bucket --jq 'map(.bucket == "pass") | all' 2>&1 || true)"
if echo "$CHECKS_OUTPUT" | grep -q "no required checks reported"; then
echo "Not required: $CHECKS_OUTPUT"
elif [[ "$CHECKS_OUTPUT" == "true" ]]; then
echo "$CHECKS_OUTPUT"
else
echo "PR state failed? $CHECKS_OUTPUT"
exit 1
fi
- name: Automerge if wgutils approves
env:
GH_TOKEN: ${{ github.token }}
run: |
if yarn wgutils can-automerge "${{ github.event.pull_request.number }}" "${{ github.event.pull_request.head.sha }}"; then
gh pr merge "${{ github.event.pull_request.number }}" --squash --auto --match-head-commit "${{ github.event.pull_request.head.sha }}"
fiCurrent limitations
These are known limitations of the software that we won't bother to address unless there's a need to do so:
- Primary meeting must be the first meeting in the month (otherwise 'prior meetings' is not populated correctly)
- The automerge system only works with
/agendasroot level folder currently - needs updating to work with the configured agendas path.
