Skip to content

Changelog

[Unreleased]

Fixed

  • Declare the licence as MIT. LICENSE has always contained the MIT text, but its heading and the 3.0.0 package metadata said GPL v3.

Security

  • Fuzzing of the cctray and GitHub runs parsers with ClusterFuzzLite
  • CodeQL analysis of the Python code
  • SECURITY.md with the supported versions, how to report a vulnerability and the disclosure timeline
  • Releases and nightlies carry a buildnotify-<version>.intoto.jsonl provenance asset

[3.0.0] - 2026-10-02

Breaking changes

  • Python 3.11 or newer is required
  • PyQt5 is replaced by PySide6 (>= 6.8)
  • Server URLs must use http:// or https://. file:// URLs are rejected in the server dialog, since they could never be fetched
  • Custom script #status# and #projects# placeholders are now shell-quoted, with quoting that follows the surrounding quotes. Scripts that relied on the raw, unquoted text need updating
  • On Windows a custom script that uses #status# or #projects# is not run. Use the BUILDNOTIFY_STATUS and BUILDNOTIFY_PROJECTS environment variables instead
  • Settings move to a versioned layout on first start. 2.x can't read them afterwards
  • Install with uv tool install buildnotify or pipx install buildnotify. The setuptools, paver, tox and Vagrant files are gone
  • The snap is retired. Flatpak replaces it

Added

  • Option to show last build label by @Deuchnord
  • BUILDNOTIFY_STATUS and BUILDNOTIFY_PROJECTS environment variables for the custom script
  • Automatic migration of 2.x settings, keeping the old keys until the new ones are saved
  • --settings PATH to use an INI settings file, and --debug to log every fetch
  • Failing projects listed in the tray tooltip
  • Symbolic tray icons that differ by shape, with a preference to turn them on
  • The tray count overlay is sharp on HiDPI screens
  • All servers are polled in parallel
  • User-Agent is BuildNotify/<version>, without the OS and kernel version
  • Flatpak manifest (packaging/flatpak) and AppStream metadata under the io.github.anaynayak.BuildNotify app id. The desktop file and icon are renamed to match
  • Preferences, the server dialog, the About box and the no-tray message open centred on the screen under the mouse pointer, kept inside the usable area, instead of in a corner of the primary screen
  • The server dialog hides the Advanced section for GitHub servers, where it had held only the time zone, which applies to cctray feeds. It comes back when you switch to cctray, with the time zone you had chosen
  • Mute a server or a project from the tray menu's Mute submenu, which has one submenu per server with a Mute whole server toggle followed by that server's projects. You can also pause all notifications for an hour. Muted servers and projects, including every project on a muted server, get no notifications, don't run the custom script, and don't affect the tray icon colour, the failing count or the badge. They stay in the menu with a dimmed icon and a (muted) suffix, and the tooltip adds N muted. Unmuting updates the tray at once. Pausing notifications doesn't change the icon. Mutes and the pause survive a restart
  • Settings move to schema version 5, which gives each server a source type and a muted flag. Existing servers become cctray feeds and start unmuted
  • The tray menu's Failing, Building, Passing and Unknown headers are disabled rows with separators between groups,. Native macOS menus don't draw Qt section titles, so they had gone missing or shown as unlabelled groups. A server with no projects shows a single Mute <server> checkbox
  • Project rows say which server they belong to. A GitHub server with no prefix labels its rows with the repository name, such as [hello-world] CI (main), and an explicit prefix still wins. A cctray project with no prefix whose name also appears on another server gets that server's host in brackets. Notifications and the tooltip use the same label; muting and change detection still go by server and project name
  • Symbolic tray icons keep at least 3:1 contrast on both light (#f0f0f0) and dark (#2b2b2b) panels: the failure cross is now a lighter red and the grey a little darker. Below 20 px, which includes the 16 px icons used on Windows, the tray badge shows ! instead of a count that would be unreadable
  • When no system tray is found, the message says BuildNotify needs a system tray and, on GNOME, names the AppIndicator and KStatusNotifierItem Support extension. The box shows the BuildNotify icon and title. BuildNotify still exits with code 1
  • The server dialog's time zone and certificate checks sit in a collapsed Advanced section that opens by itself when either is set. The field is now Time zone for feed times, its default entry reads Use the feed's offset (stored as before), and you can type part of a zone name, such as Kolkata, to find it
  • Labels and buttons in Preferences and the server dialog have Alt-key mnemonics, such as Alt+S for Save, with none repeated on a page. The project filter, project list and server list have names for screen readers
  • A Check now item in the tray menu polls every server immediately. Menu items now read Preferences... (Settings... on macOS), About BuildNotify and Quit BuildNotify (Exit on Windows), and the About box describes cctray feeds and GitHub Actions and links to the project page
  • Tray icons tell more states apart. Success while building now has a ring, so it no longer looks like plain success, and the same ring marks failure while building. When every server is down and none has projects from an earlier fetch, the icon is a hollow slashed square (a slashed circle in the symbolic set) instead of the grey used for an unknown status. The tooltip also shows the server count and Notifications paused until HH:MM while paused
  • The server dialog's sign-in choices are None, Username and password and Token. None hides both fields and saves no credentials. Without a keyring, the dialog says credentials can't be stored and names the keyring package to install. A saved cctray bearer token is labelled as a token instead of Password
  • The certificate prompt now names the host and says it turns off certificate checks for that server. After accepting, the dialog shows Certificate checks off for <host> with a Turn checks back on button
  • The GitHub form links to token creation, says the token needs Actions: read and that GitHub allows 60 requests an hour without one, and accepts a pasted https://github.com/owner/name URL as the repository
  • The server dialog's project list has a filter field, an All (N of M) box that shows a partial state when some projects are unticked, a note that new projects in the feed are included automatically, and middle-elided names with the full name as a tooltip
  • A Failing first sort order, the default for new installs, puts building projects first within each tray menu section, then the newest builds. Existing installs keep their sort order
  • Unavailable servers get a menu row with their last error and when it happened. The error is one short line with the host but no full URL or credentials
  • GitHub Actions servers: pick "GitHub Actions" in the server dialog and enter a repository, with optional workflow and branch filters. The latest run of each workflow and branch shows as a project. When a workflow filter matches no finished run in the newest 100 runs, BuildNotify reads up to 4 older pages to find one. The token stays in the system keyring, and BuildNotify waits out GitHub's rate limits on every server that uses the same token. A server with no token, for a public repository, writes nothing to the keyring
  • With no servers the tray menu says "No servers yet" and offers "Add a server...", which opens the server dialog. Pause and Mute are hidden until a server is configured, and the tooltip says "No servers configured" instead of "No failing builds"
  • On the first launch with no servers, the server dialog opens once. A first_run/server_prompt_shown setting stops it opening again
  • Clicking a notification about one project opens its page. Clicking one about several projects or a server opens the tray menu
  • A " is reachable again" notification follows a connectivity notification once the server answers. The custom script runs for it with BUILDNOTIFY_STATUS set to Connectivity restored

Changed

  • The Servers tab shows each server as a row with its name (prefix, else host), source kind, target (host, or repository with workflow@branch) and the project count from the last poll. The buttons read Add..., Edit... and Remove, with Insert, Enter and Delete shortcuts, and Remove asks for confirmation
  • Preferences is split into Servers, Menu, Notifications and Advanced tabs, with sentence-case labels, OK and Cancel buttons, and the request timeout and custom script example exposed. The docs screenshots follow the new tabs
  • The tray menu groups projects under Failing, Building, Passing and Unknown headers with counts, so the status no longer depends on the icon colour alone. Empty sections are left out
  • With more than 15 projects, passing projects collapse into a Passing (N) submenu so the tray menu fits on screen. Failing and building projects stay top level
  • Long project names in the tray menu are shortened in the middle to a fixed width, so the job name and build time are no longer cut off. The tooltip shows the whole name
  • Build times in the tray menu are compact, such as 18m, 11h or 3d, instead of 18 minutes ago
  • Notification titles name the project or count the builds, such as Build failed: nightly, 3 builds failed, Build fixed: nightly, Still failing: nightly, Build passed: nightly and Can't reach ci.example.org, instead of Broken builds or Yet another successful build. A notification lists at most three names, then and N more. The custom script still gets the old titles in BUILDNOTIFY_STATUS and every name in BUILDNOTIFY_PROJECTS
  • Failure and connectivity notifications use the warning icon instead of the information icon
  • When every server is down and nothing is cached, the tray tooltip says "Can't reach any server" instead of "No failing builds"
  • A server error row in the tray menu reads like jenkins: can't connect (10:00): the server's menu prefix or host, then a short reason such as can't connect, server not found, timed out, sign-in failed, not found, not a cctray feed, certificate not trusted or GitHub rate limit reached. The row is no longer greyed out, and opens a submenu with the full error, a hint, Retry now and Edit server...
  • The server dialog is a single page with Cancel and Save. Save works without loading the server first, so a server that is down can be added, and all of its projects are included. Load is now Test connection, which shows the project count or a short error next to the button and lists the projects below. Editing a server without testing it keeps its excluded projects. Changing the URL, repository or source type clears the test result and its project list
  • The server dialog is titled "Add server" for a new server and "Edit server - " when editing one
  • A feed URL typed without a scheme, such as ci.example.org/cc.xml, gets https:// added instead of an error
  • Server dialog validation errors show under the field instead of in a message box, when the field loses focus or on Load. "Path to cctray.xml" is now "Feed URL", and an empty one says "Enter the feed URL."
  • The failing count on the tray icon is a red badge in the bottom-right corner, so it no longer covers the icon. Counts above 99 show as 99+
  • Bearer and GitHub tokens are stored in the keyring under the username token instead of an empty username, which keyring deprecates. Tokens saved by earlier versions are still read, and move to the new entry the next time settings are saved

Fixed

  • The tray icon keeps the same size in every state on macOS. After a poll the icon with a count badge or a muted dimming was a single 22 px picture while the launch icon was a 128 px one, so the menu bar scaled them differently and the icon looked smaller. Every state is now built the same way, with 1x and 2x pictures of the same size
  • GitHub Actions servers no longer list Dependabot's dynamic runs (event dynamic, workflow path under dynamic/), which added a new row for every run with its run number in the name
  • Accepting the certificate prompt in the server dialog turns off certificate checks only for that host. Changing the feed URL to another host turns them back on
  • Saving Preferences no longer cancels a pause set from the tray while the dialog was open
  • Saving Preferences no longer reverts servers or projects muted or unmuted from the tray while the dialog was open
  • Saving Preferences no longer lowers the default 120 s polling interval to 60 s. The interval can be set from 10 seconds to an hour
  • Configure in Preferences is enabled when a server is selected with the keyboard, not only with a mouse click, and Enter opens the selected server for editing
  • Shell injection through project names in the custom script
  • Crash on non-XML server responses
  • Feeds without a <Projects> root are reported as errors instead of showing 0 projects
  • Feeds are parsed with defusedxml
  • Keyring errors no longer crash polling, and the keyring is only touched when credentials are set
  • lastBuildTime parsing with timezone offsets, using zoneinfo
  • Fetches no longer run on the GUI thread when preferences are saved
  • A reload during a fetch triggers a new fetch instead of being dropped
  • The overall status ranks every failure above every success, and Exception counts as a failure
  • New builds are detected by build time as well as label
  • Last known projects are kept while a server is unavailable, and the connectivity back-off resets on recovery
  • A new failing project is notified as broken
  • The custom script text is kept when the script is disabled
  • Server list editing: empty lists are saved, Remove with no selection is ignored, edited URLs update the list, duplicates are rejected, and removed servers lose their settings and keyring entry
  • Added servers are saved only when Preferences is accepted
  • Editing a server keeps its SSL verification setting
  • Bearer authentication sends only the Bearer token
  • The server dialog's Load has a total deadline
  • The SSL retry prompt shows a No button and defaults to No
  • The no-tray message is shown, and startup waits for the tray
  • Quitting goes through the event loop, waits a bounded time for fetch threads and hides the tray icon at once
  • The preferences and server dialogs are deleted after they close
  • Future build times read "in ..." instead of "... ago", and the 30-day boundary is fixed

Tech

  • just demo runs the app against local fixture feeds with throwaway settings and no keychain
  • just screenshots renders the docs images offscreen from fixture data
  • The release workflow fails when the tag doesn't match the version in buildnotifylib/version.py
  • The Flatpak bundle drops Qt WebEngine and NumPy
  • The Preferences and server dialogs are built in Python code. The Qt Designer .ui files, the generated modules and just ui are gone
  • pyproject.toml with hatchling, uv and uv.lock
  • ruff for lint and format, mypy in CI with strict typing for core and adapters
  • justfile and pre-commit hooks
  • CI on Python 3.11-3.14 on Linux, plus macOS and Windows
  • PyPI releases from v* tags with trusted publishing
  • Weekly grouped Dependabot updates
  • Pure core model, cctray parser, aggregate, diff, back-off and humanize, with adapters for http, credentials, settings and hooks
  • Icons load from package data instead of a Qt resource module
  • Hermetic tests: no real keychain or QSettings

[2.1.0] - 2021-01-03

Tech

  • Type declarations, mypy for static type checker
  • Use github actions for running builds
  • Bump dependencies

Added

  • Show context menu on left click for non-darwin platforms
  • Bearer token authentication by @Deuchnord
  • Enhance config windows UX by @Deuchnord
  • Snaps are automatically pushed to https://snapcraft.io/buildnotify-test

[2.0.0] - 2019-08-16

Added

  • Bump to Python3

[1.0.4] - 2017-12-14

Added

  • Codeclimate for test coverage
  • Deployment to testpypi

Fixed

  • Add http scheme in cctray.xml feed if missing
  • Preferences dialog uses available space on resize
  • Server configuration without exclusion no longer causes failure

[1.0.3] - 2017-12-14

Fixed

  • Fixed bug with url scheme detection.

[1.0.2] - 2017-12-13

Fixed

  • Fixed blocker bug with .desktop file leading to installation failure

[1.0.1] - 2017-12-09

Fixed

  • Fixed bug with missing icon
  • App crash on network connectivity issue

[1.0.0] - 2017-08-17

Added

  • Sort projects by last build time or name
  • Allow selection/deselection of all projects in configuration screen
  • Using keychain to manage passwords
  • Support for self-signed certificates
  • Per CI server build label prefix
  • Support for projects without URL scheme specified in the cctray.xml feed
  • Upgrade to PyQt5

Changed

  • Allow polling unit to seconds from minutes.
  • List of projects can now be dragged to extend the visible list

Fixed

  • Encoding of username/password for basic authentication
  • Projects with same name across CI servers are handled correctly