Skip to content

Add experimental Backport Dashboard#531

Open
korthout wants to merge 23 commits intomainfrom
backport-dashboard
Open

Add experimental Backport Dashboard#531
korthout wants to merge 23 commits intomainfrom
backport-dashboard

Conversation

@korthout
Copy link
Owner

@korthout korthout commented Jan 2, 2026

This PR introduces a new experimental feature: the Backport Dashboard.

Description

When enabled, the action maintains a single GitHub Issue that tracks the status of all backport pull requests created by the action. This provides maintainers with a centralized view of outstanding backports that need attention.

Check the Backport Dashboard in korthout/backport-action-test#404 to see it in action.

Features

  • Creates and updates a "Backport Dashboard" issue listing original PRs and their associated backport PRs.
  • Adds new backports to the list automatically as they are created.
  • Automatically removes entries from the dashboard once all backports for a PR are merged or closed, keeping the list focused on active work.

Security & Robustness

  • Robust Parsing: Implements a strict, line-by-line parser that produces data that is only used to construct the dashboard's body, protecting the action from injection attacks.
  • Sanitization: PR titles are sanitized (newlines removed) and branch names are escaped (backticks handled) to prevent rendering issues.
  • Concurrency Safety: We recommend using GitHub Action's concurrency groups to prevent race conditions during dashboard updates.

Configuration

To enable the dashboard, add dashboard_enabled: true to the experimental input.

To create and update the dashboard, the action requires issues:write permissions in addition to the others. Additionally, it is recommended to configure concurrency to prevent serial updates to the dashboard from causing issues.

permissions:
  contents: write # so it can comment
  pull-requests: write # so it can create pull requests
  issues: write # so it can create/update the dashboard issue
jobs:
  backport:
    runs-on: ubuntu-latest
    # Serialize runs to prevent race conditions on the dashboard
    concurrency:
      group: backport-dashboard
      cancel-in-progress: false
    steps:
      - uses: actions/checkout@v4
      - name: Create backport pull requests
        uses: korthout/backport-action@v4
        with:
          experimental: >
            {
              "dashboard_enabled": true
            }

Future extension options

I see potential to extend this in ways to make it more flexible. Currently, it's just a flag to enable/disable it, but we could add additional inputs to control the feature. For example, dashboard_issue_number would allow directly specifying the issue by number. Another example, would be to allow running the action only to clean up completed backport without actually creating new backports in a workflow that runs periodically.

This adds a new input dashboard_enabled that allows the action to create
or update a single GH issue for tracking the status of backport pull
requests, i.e. the backport dashboard.

The dashboard can be found by title, or created newly if it doesn't
exist yet.

The issue is used as a database, so it's contents are parsed and can be
updated again. This means that users can manually track backport pull
requests that were created before the introduction of this feature
simply by editing the dashboard issue.

Before releasing this, we'll need to consider the security implications
of parsing user-editable data.
Don't let it depend on whether there are any pending backports. For
users, it will be useful to inspect the dashboard regardless.
If the error is Resource not accessible by integration then this
indicates a missing permission to write issues.
The goal is that we track pending backports, because we want to ensure
that each original PR that required backporting is also actually fully
backported eventually, i.e. merged.

However, any closed backport pull request is likely closed
intentionally. It can be considered as the closer stating: this backport
is no longer required. Of course, it could be that a manual backport is
still performed separately, but that's not a PR created by backport
action, so it can't track it.

For the purpose of tracking pending backport pull requests created by
the action, I believe we can simply consider closed backports as no
longer active.
Once all backports are merged or closed, we can remove the entire entry.
Expands the description header used in the dashboard issue with more
details, including how it works and what it's for.

I've also separated the list from the header with a horizontal line.
We'll need to somehow avoid that issues accidentally get overwritten.
For example, when someone creates a new issue with the exact title
'Backport Dashboard' then it could be found by the action and updated,
overwriting the original contents.

Of course, GitHub offers a version history for each issue, but we can
provide some ways to avoid this issue.

One way to do so would be to allow the workflow owner to specify the
dashboard issue by id. However, we don't have that option yet.

However, we need a good default behavior. We can simply make the choice
to select only the oldest open Backport Dashboard issue. It's up to the
maintainer to ensure that there is no older issue with the same title.
This way, newer issue will never conflict.

The only cases where this can fail, is that an older issue with the same
title is reopened, or an older open issue is renamed. To avoid these,
we'll need to support an input that allows specifying the issue id
directly. We can do that later.
GitHub automatically renders pull requests with title already.

Note that we need to be able to parse the dashboard regardless. For
testing purposes, I could simply manually change previous dashboards,
but in the future we'll need to be able to stay backward compatible. So
some versioning is needed.
To render the header correctly, we cannot use an inline comment.
Instead, the version comment must be placed on another line. We can keep
it on the first line though.
Provides tests for the basic functionality.

Dashboard
✓ creates a new dashboard with a new entry
✓ removes older entries that are completed
✓ keeps older entries that are still pending
✓ adds new backports to existing entries
✓ handles version 0 dashboard format
References to backports created in a downstream repo should be
referenced differently from local backport pull requests.
There were several issues with the previous parsing mechanism based on
regex. By parsing more explicitly we have more control and can more
easily handle and ignore malformed parts. It also allows us to correctly
parse some special cases like backticks in the target branch. Lastly, we
now ignore dashboards that are fully malformed, i.e. they don't have a
version specified.
This helps avoid two cases:
- newlines in PR titles resulting in incorrect rendering
- backticks in target branch result in incorrect rendering
Users should be aware that they are expected to not edit the dashboard
issue. Additionally, we can use the note to request bug reports while
it's experimental.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an experimental "Backport Dashboard" feature that maintains a centralized GitHub issue tracking the status of all backport pull requests created by the action. The dashboard automatically updates to show only active backports, removing entries once all associated backports are merged or closed.

Key Changes

  • New Dashboard class with robust parsing and rendering logic to manage a tracking issue
  • Integration into the backport workflow when dashboard_enabled: true is set
  • Support for both same-repo and downstream-repo backport scenarios

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/dashboard.ts Core implementation of dashboard creation, parsing, and updating logic with sanitization
src/test/dashboard.test.ts Integration tests for dashboard create/update operations
src/test/dashboard_parsing.test.ts Tests for robust parsing of dashboard markdown with injection protection
src/test/dashboard_rendering.test.ts Tests for rendering dashboard with proper sanitization and escaping
src/github.ts Added API methods for issue management (getIssues, createIssue, updateIssue) and extended types
src/backport.ts Integrated dashboard updates into the backport workflow
action.yml Added dashboard_enabled configuration option to experimental features
README.md Documentation for the new dashboard feature and configuration examples

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

It wasn't clear that the issues:write permissions were only needed for
when the dashboard is enabled. As this is an experimental feature it
should not be part of the main doc.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

korthout and others added 3 commits January 2, 2026 14:17
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
It was possible to track an original pr if backport-action ran for it
but it didn't create any backports. Such PRs should not be tracked.
@korthout
Copy link
Owner Author

korthout commented Jan 3, 2026

@yafanasiev Does this feature appeal to you? If so, I'd love a human review of it before merging. If not, or if you don't have time, then I'll go ahead and merge it, as it's currently an experimental feature and doesn't affect the core functionality. Let me know 🙇

PS: happy new year 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants