Skip to content

Instantly share code, notes, and snippets.

@Gpx

Gpx/README.md Secret

Last active November 6, 2025 13:18
Show Gist options
  • Select an option

  • Save Gpx/fff71c27a9975c56ad594f35eb1a6666 to your computer and use it in GitHub Desktop.

Select an option

Save Gpx/fff71c27a9975c56ad594f35eb1a6666 to your computer and use it in GitHub Desktop.
Queue Notifier

Queue Notifier

Notifies you when your build is removed from GitHub’s Merge Queue.

Note

Currently works only on macOS.

Installation

You need two things:

  1. npx which you can get with Node.js
  2. gh (GitHub CLI) and you must be logged in

Usage

Run:

npx zx https://gist.githubusercontent.com/gpx/fff71c27a9975c56ad594f35eb1a6666/raw/qn.mjs org name pr

Ok, that's long, so mabye create an alias:

alias qn='npx zx https://gist.githubusercontent.com/gpx/fff71c27a9975c56ad594f35eb1a6666/raw/qn.mjs'
qn org name pr

Make it permanent by adding the alias to your shell profile (e.g. ~/.zshrc or ~/.bashrc).

org/name/pr is your GitHub organization, repository, and pull request number. Example:

qn acme-inc better-db 123

If you work often with an organization or a repository you can create more aliases:

alias qn='npx zx https://gist.githubusercontent.com/gpx/fff71c27a9975c56ad594f35eb1a6666/raw/qn.mjs'
alias qn-acme='qn acme'
alias qn-bdb='qn-acme better-db'

qn-acme foo 2 # Will check PR 2 for acme/foo
qn-bdb 1 # Will check PR 1 for acme/better-db

That is it. Let the script run. A notification window will appear when the build is merged or removed from the queue.

#!/usr/bin/env zx
/*
* Queue Notifier
* ---------------
* Author: Giorgio Polvara (@gpx)
* Description:
* Watches a GitHub pull request in a merge queue and notifies
* you when it gets merged or removed.
*
* Requirements:
* - Node.js with zx (`npx zx <script>`)
* - GitHub CLI (`gh`) authenticated and available in PATH
* - macOS (uses `afplay` and `osascript` for notifications)
*
* Usage:
* npx zx qn.mjs <org> <repo> <prNumber>
*
* License: MIT
*/
if ((await which("gh", { nothrow: true })) === null) {
console.error("This script requires the GitHub CLI (gh) to be installed.");
process.exit(1);
}
if (argv._.length !== 3) {
console.error("Invalid input format. Expected format: org repo prNumber");
process.exit(1);
}
const [org, repo, prNumber] = argv._;
async function checkPR(org, repo, prNumber) {
let isInMergeQueue, mergedAt;
while (true) {
const pullRequest = JSON.parse(
await $`gh api graphql --paginate -f query='
query {
viewer {
organization(login: "'${org}'") {
repository(name: "'${repo}'") {
pullRequest(number: ${prNumber}) {
isInMergeQueue
mergedAt
}
}
}
}
}
' --jq '.data.viewer.organization.repository.pullRequest'`
);
isInMergeQueue = pullRequest.isInMergeQueue;
mergedAt = pullRequest.mergedAt;
if (!isInMergeQueue || mergedAt) {
break;
}
await sleep(10_000);
}
return mergedAt;
}
const mergedAt = await spinner(
`Checking ${org}/${repo}#${prNumber}`,
async () => await checkPR(org, repo, prNumber)
);
$`afplay /System/Library/Sounds/Glass.aiff`;
if (mergedAt) {
console.log(`PR #${prNumber} has been merged at ${mergedAt}`);
await $`osascript -e 'display dialog "PR #${prNumber} has been merged at ${mergedAt}" with title "Success" buttons {"OK"}'`;
} else {
console.log(`PR #${prNumber} is no longer in the merge queue`);
await $`osascript -e 'display dialog "PR #${prNumber} is no longer in the merge queue" with title "Info" buttons {"OK"}'`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment