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 wgutils
wgutils init
Create an example wg.config.js file with the wgutils init command:
wgutils init
Then 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 to false for repositories that do not manage meetings, such as spec-only repositories
spec (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 version
mainFile - the file that gets fed into spec-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 newline
liveNotesUrl - the URL to the Google Doc that is used for the live notes
attendeesTemplate - a markdown table for your attendees to populate
timezone - US/Pacific or UTC or similar; what time governs your meeting times. Critical for international daylight savings time.
frequency - monthly or weekly - how frequently do you meet
weekday - M, Tu, W, Th, F, Sa or Su - 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 the weekdays do you meet on?
secondaryMeetings - are there additional meetings? If so, a list of them:
nth - which instance
dayOffset (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 meeting
description (optional) - a description for this secondary meeting
filenameFragment (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 being 1 right 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 agendas
description (optional) - description of the working group; will appear in agendas
dateAndTimeLocations (optional) - the locations to add to the end of the dateandtime.com URL for the time of the meeting
filenameFragment (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 the description)
repoSubpath (optional) - if the agendas/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 to repoSubpath (or the repo root)
For a repository that only manages a specification and does not manage meetings,
the configuration can omit all meeting options:
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 4
wgutils 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 September2026
Use --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 --debug
wgutils 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 }}"
fi
Current 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 /agendas root level folder currently - needs updating to work with the configured agendas path.
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
wgutils init
Create an example
wg.config.jsfile with thewgutils initcommand:Then 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.mdMeeting options, required unless
meetings: falseis 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 filenameWhen
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 filenameOptions 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:
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 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 requiresspec.title,spec.urlandspec.mainFileinwg.config.js(use withmeetings: falsefor spec-only repos).Example: generate the
September2026spec changelog:Use
--currentto compare against a commit other thanHEAD. Use--previous MonthYYYY(or--no-previous) to override the autodetected previous tag. Use--forceto allow an unexpected tag name (e.g. out of date) and/or overwrite an existing changelog. Use--debugfor verbose logging. These together are useful for validating the script output from previous version runs.wgutils spec release
Release the result of a previous
wgutils spec versioncommand by:The tag must match the previous
wgutils spec versionrun and this command must run onmainafter the draft release has been merged.wgutils can-automerge
First, and SUPER IMPORTANT, make sure that your
mainbranch 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:
Current limitations
These are known limitations of the software that we won’t bother to address unless there’s a need to do so:
/agendasroot level folder currently - needs updating to work with the configured agendas path.