Skip to content

feat: sync linked issue labels to pull requests#1877

Draft
cheese-cakee wants to merge 24 commits intohiero-ledger:mainfrom
cheese-cakee:feat/sync-issue-labels
Draft

feat: sync linked issue labels to pull requests#1877
cheese-cakee wants to merge 24 commits intohiero-ledger:mainfrom
cheese-cakee:feat/sync-issue-labels

Conversation

@cheese-cakee
Copy link
Contributor

Description

Adds an automated GitHub workflow + bot script to sync labels from linked issues to pull requests.

When a PR body includes closing keywords (for example Fixes #123), the workflow fetches labels from those linked issues and adds missing labels to the PR.

Related issue(s)

Fixes #1716

What changed

  • Added compute workflow: .github/workflows/sync-issue-labels-compute.yml
    • Uses pull_request_target on opened, edited, reopened, synchronize, and ready_for_review
    • Includes secure defaults (harden-runner, checkout main, pinned action SHAs)
    • Supports workflow_dispatch with pr_number + dry_run
    • Computes labels from linked issues and uploads as artifact
  • Added add workflow: .github/workflows/sync-issue-labels-add.yml
    • Triggered by workflow_run (not pull_request_target)
    • Uses actions-ecosystem-add-labels action to add labels
    • Runs with write permissions
  • Added script: .github/scripts/sync-issue-labels.js
    • Skips bot/dependabot PRs
    • Parses linked same-repo issue references from closing keywords (fixes/closes/resolves)
    • Aggregates labels from all linked issues (deduplicated)
    • Adds only missing labels to the PR (idempotent/additive)
    • Returns labels for workflow consumption
  • Added changelog entry under [Unreleased] -> .Github

Scope note

This PR intentionally implements label sync only (additive). It does not remove labels from PRs and does not include assignee sync.

Architecture

Two separate workflows to avoid pull_request_target limitations (per exploreriii feedback):

  1. sync-issue-labels-compute.yml - reads labels (runs in pull_request_target context)
  2. sync-issue-labels-add.yml - writes labels (runs in workflow_run context with write permissions)

Testing

  • node --check .github/scripts/sync-issue-labels.js

Checklist

  • Documented (workflow + script behavior is self-logged and changelog updated)
  • Tested (syntax check)

@github-actions
Copy link

[commit-verification-bot]
Hi, this is VerificationBot.
Your pull request cannot be merged as it has 1 unverified commit(s):

  • a30af72 feat: sync linked issue labels to pull requests

View your commit verification status: Commits Tab.

To achieve verified status, please read:

Remember, you require a GPG key and each commit must be signed with:
git commit -S -s -m "Your message here"

Thank you for contributing!

From the Hiero Python SDK Team

@cheese-cakee cheese-cakee force-pushed the feat/sync-issue-labels branch from a30af72 to 1593e8e Compare February 26, 2026 19:19
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a two-stage GitHub Actions system plus a Node.js script that detect issues linked in a PR body, collect those issues' labels, and apply missing labels to the pull request; includes artifact exchange between workflows, dry-run support, bot/fork safeguards, and a small runner egress allowlist update.

Changes

Cohort / File(s) Summary
Compute Workflow
​.github/workflows/sync-issue-labels-compute.yml
New workflow triggered on PR events and workflow_dispatch: hardens runner, runs sync-issue-labels.js to compute labels, writes labels.json, uploads artifact pr-labels-${PR_NUMBER}, and dispatches the add workflow with upstream run id and inputs.
Add Workflow
​.github/workflows/sync-issue-labels-add.yml
New workflow (workflow_dispatch) that downloads the artifact from the compute run, parses labels.json (no-op if missing), exports outputs, and conditionally adds labels to the PR (respects dry-run, fork PRs, and source_event guards).
Script
​.github/scripts/sync-issue-labels.js
New Node.js action entry script exported via module.exports = async ({ github, context }) => {}: resolves PR context, skips bot-authored PRs, parses closing-references in PR body for issue numbers, fetches each issue (skips PR refs, handles 404), aggregates/normalizes/deduplicates labels, computes delta vs PR labels, logs progress, and applies labels (unless dry-run). Returns labels-to-add for observability.
Changelog
CHANGELOG.md
Updated header formatting and added an Unreleased entry documenting the new workflows and sync script; removed one unrelated doc entry.
Runner Harden config (allowlist)
​.github/workflows/pr-check-test.yml
Allowed-endpoints entry added to Harden the runner step to permit outbound HTTPS to ziply.mm.fcix.net:443.

Sequence Diagram

sequenceDiagram
    actor GitHub as GitHub
    participant ComputeWF as "Compute Workflow"
    participant Script as "sync-issue-labels.js"
    participant API as "GitHub API"
    participant AddWF as "Add Workflow"

    GitHub->>ComputeWF: PR opened/edited/reopened/synchronize or workflow_dispatch
    ComputeWF->>ComputeWF: Harden runner, checkout repo
    ComputeWF->>Script: Run script with PR number & dry_run
    Script->>API: Fetch PR details (if needed)
    Script->>Script: Parse PR body for linked issue numbers
    Script->>API: Fetch each linked issue (skip PR refs, handle 404)
    Script->>Script: Aggregate, normalize, dedupe labels
    Script-->>ComputeWF: Return labels, has_labels, pr_number, dry_run
    ComputeWF->>ComputeWF: Write `labels.json` and upload artifact `pr-labels-${PR_NUMBER}`
    ComputeWF->>GitHub: Dispatch add workflow with artifact run id & inputs
    GitHub->>AddWF: Start Add Workflow
    AddWF->>AddWF: Harden runner, download artifact, read `labels.json`
    AddWF->>API: Apply missing labels to target PR (unless dry-run or fork)
    API-->>AddWF: Confirm labels applied
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: sync linked issue labels to pull requests' directly and clearly summarizes the main change: automating label synchronization from linked issues to PRs.
Description check ✅ Passed The description comprehensively explains the automation added, the workflow trigger events, the script logic for parsing and applying labels, and the related issue. It is clearly related to the changeset.
Linked Issues check ✅ Passed The PR addresses both linked issues: implements security hardening per #123 (harden-runner, pinned actions, least-privileged permissions) and implements label-sync automation per #1716 (parse closing keywords, deduplicate, apply labels).
Out of Scope Changes check ✅ Passed All changes are in scope: two workflows and one script for label sync, a changelog entry, and a minor network endpoint allowlist addition for CI. No extraneous changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #1716

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4


ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 61a6f38 and a30af72.

📒 Files selected for processing (4)
  • .github/scripts/sync-issue-labels.js
  • .github/workflows/sync-issue-labels-add.yml
  • .github/workflows/sync-issue-labels-compute.yml
  • CHANGELOG.md

Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

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

@cheese-cakee I appreciate you having another go at this 🥇
Could you please test this on a fork so we see how it does with real github data

@codecov
Copy link

codecov bot commented Feb 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1877   +/-   ##
=======================================
  Coverage   93.53%   93.53%           
=======================================
  Files         141      141           
  Lines        9146     9146           
=======================================
  Hits         8555     8555           
  Misses        591      591           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link

Hi, this is MergeConflictBot.
Your pull request cannot be merged because it contains merge conflicts.

Please resolve these conflicts locally and push the changes.

Quick Fix for CHANGELOG.md Conflicts

If your conflict is only in CHANGELOG.md, you can resolve it easily using the GitHub web editor:

  1. Click on the "Resolve conflicts" button in the PR
  2. Accept both changes (keep both changelog entries)
  3. Click "Mark as resolved"
  4. Commit the merge

For all other merge conflicts, please read:

Thank you for contributing!

@cheese-cakee cheese-cakee force-pushed the feat/sync-issue-labels branch 2 times, most recently from 9264396 to 89b455d Compare February 27, 2026 22:08
@cheese-cakee
Copy link
Contributor Author

cheese-cakee commented Feb 27, 2026

Hi @exploreriii. The Script Injection warning from Codacy is about the pull_request_target trigger. This trigger is required for this workflow because:

  1. We need to read from main branch (not PR code) for security
  2. We need the PR context to get linked issues from PR body

The workflow already has security measures in place:
ref: main checkout (not PR head - prevents malicious code execution)
harden-runner enabled
Minimal permissions: pull-requests: read, issues: read, contents: read

This is a known trade off for workflows that need to read from main while responding to PR events.
Is there a preferred way to address this, or should we document this exception in the workflow?

@cheese-cakee cheese-cakee marked this pull request as ready for review March 1, 2026 13:49
Copilot AI review requested due to automatic review settings March 1, 2026 13:49
@cheese-cakee cheese-cakee requested review from a team and removed request for andrewb1269 and Copilot March 1, 2026 13:49
@cheese-cakee cheese-cakee added help needed: github maintainers Requires input from @hiero-ledger/github-maintainers and removed status: needs developer testing labels Mar 1, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (2)
.github/workflows/sync-issue-labels-compute.yml (1)

62-62: ⚠️ Potential issue | 🔴 Critical

Do not interpolate labels JSON directly into a shell-quoted echo.

Line 62 is vulnerable to quote-breaking/injection if label text contains '. Use a quoted heredoc (or write the file in github-script) instead.

Proposed fix
       - name: Upload labels as artifact
         if: steps.compute.outputs.has_labels == 'true'
         run: |
-          echo '${{ steps.compute.outputs.labels }}' > labels.json
+          cat > labels.json <<'JSON'
+${{ steps.compute.outputs.labels }}
+JSON
         shell: bash

As per coding guidelines, “Treat all GitHub event data as potentially untrusted input… Free-form user input must not flow directly into shell commands…”.

.github/workflows/sync-issue-labels-add.yml (1)

16-16: ⚠️ Potential issue | 🟠 Major

Guard this job when workflow_run.pull_requests is empty.

Line 22 and Line 37 assume pull_requests[0] exists. Because the upstream workflow supports workflow_dispatch, this can be empty and cause runtime failure.

Proposed fix
 jobs:
   add-labels:
-    if: ${{ github.event.workflow_run.conclusion == 'success' }}
+    if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.pull_requests[0] != null }}
     runs-on: ubuntu-latest
For GitHub Actions `workflow_run` events, can `github.event.workflow_run.pull_requests` be empty when the upstream workflow was triggered via `workflow_dispatch`?

Also applies to: 22-23, 37-37


ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a30af72 and a0e10dc.

📒 Files selected for processing (4)
  • .github/scripts/sync-issue-labels.js
  • .github/workflows/sync-issue-labels-add.yml
  • .github/workflows/sync-issue-labels-compute.yml
  • CHANGELOG.md

@exploreriii
Copy link
Contributor

Did this one get fully tested on a fork for edge cases etc too?

cheese-cakee and others added 17 commits March 6, 2026 02:17
Co-authored-by: Roger Barker <roger.barker@swirldslabs.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Co-authored-by: Roger Barker <roger.barker@swirldslabs.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Co-authored-by: Roger Barker <roger.barker@swirldslabs.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Co-authored-by: Roger Barker <roger.barker@swirldslabs.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Co-authored-by: Roger Barker <roger.barker@swirldslabs.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
@cheese-cakee cheese-cakee force-pushed the feat/sync-issue-labels branch from 0db2c7c to 30512d3 Compare March 5, 2026 20:47
Signed-off-by: cheese-cakee <farzanaman99@gmail.com>
@cheese-cakee cheese-cakee requested review from a team and rbarker-dev March 5, 2026 21:30
@exploreriii exploreriii added status: needs committer review PR needs a review from the committer team status: needs maintainer review PR needs a review from the maintainer team and removed status: needs developer revision PR has requested changes that the developer needs to implement labels Mar 6, 2026
Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

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

From what i see, you upload the artifact with read permissions on main code. You could limit how much code to read.

You download and use the json with write permissions on issues, without checking out code. We can check the artefact json is as expected, before proceeding, else exiting.

i think you have prevented this workflow from running at all on PRs coming from forks (these are most of the PRs we get), this is fine way to do it if we do not tolerate any PR risk at all @rbarker-dev


- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Copy link
Contributor

Choose a reason for hiding this comment

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

i think you can narrow this to just allow checkout of certain files you need using sparse-checkout

@exploreriii exploreriii added status: needs developer revision PR has requested changes that the developer needs to implement and removed status: needs committer review PR needs a review from the committer team status: needs maintainer review PR needs a review from the maintainer team labels Mar 7, 2026
@exploreriii exploreriii marked this pull request as draft March 7, 2026 20:03
@github-actions
Copy link

Hello, this is the OfficeHourBot.

This is a reminder that the Hiero Python SDK Office Hours are scheduled in approximately 4 hours (14:00 UTC).

This session provides an opportunity to ask questions regarding this Pull Request.

Details:

Disclaimer: This is an automated reminder. Please verify the schedule here for any changes.

From,
The Python SDK Team

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

Labels

status: needs developer revision PR has requested changes that the developer needs to implement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Intermediate]: Create a workflow to copy over the issue labels, type to the PR labels

6 participants