ci: add GitHub issues to Azure DevOps sync workflow#527
Open
Yetkin Timocin (ytimocin) wants to merge 2 commits into
Open
ci: add GitHub issues to Azure DevOps sync workflow#527Yetkin Timocin (ytimocin) wants to merge 2 commits into
Yetkin Timocin (ytimocin) wants to merge 2 commits into
Conversation
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
March 19, 2026 01:34
93a0cd9 to
7c81ab3
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
2 times, most recently
from
March 26, 2026 19:20
2f93de4 to
e2d33db
Compare
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
2 times, most recently
from
April 1, 2026 23:57
e8ba3bf to
a02af47
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Actions workflow to synchronize maintainer-approved GitHub issues into Azure DevOps (ADO) work items, using direct REST API calls and a label/environment gate to control trust boundaries.
Changes:
- Introduces
.github/workflows/sync-issues-to-ado.ymlto sync issues labeledado-sync(and support manualworkflow_dispatch). - Implements ADO work item create/update + state mapping via
curl/jqand a WIQL lookup keyed by a GitHub-derived tag. - Posts a link-back comment on the GitHub issue pointing to the corresponding ADO work item.
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
April 6, 2026 19:18
a02af47 to
810de89
Compare
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
April 9, 2026 17:30
810de89 to
1fbfaa1
Compare
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
3 times, most recently
from
April 23, 2026 18:12
47c1061 to
8d1e5f0
Compare
| - name: Resolve issue details | ||
| id: issue | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} |
There was a problem hiding this comment.
💡 Thoughts, only - but something you/we should consider https://docs.github.com/en/actions/tutorials/authenticate-with-github_token
| # [Workflow dispatch] Manual trigger for ad-hoc syncing of specific issues | ||
| workflow_dispatch: | ||
| inputs: | ||
| issue_number: |
There was a problem hiding this comment.
💡Thought Share: Consider requiring review for access to secrets
https://docs.github.com/en/actions/reference/security/secure-use
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
April 28, 2026 17:11
8d1e5f0 to
ef99c81
Compare
Yetkin Timocin (ytimocin)
added a commit
to ytimocin/kubefleet
that referenced
this pull request
Apr 28, 2026
Address inline review comments on PR kubefleet-dev#527: * Gate the `labeled` event on `github.event.label.name == 'ado-sync'` so adding any unrelated label to an issue that already has `ado-sync` no longer re-triggers a sync. Closed/reopened keep the label-presence check because the action payload omits `label.name` there. * Paginate the `listComments` call before the link-back-marker dedupe check, otherwise the marker is missed when the issue has more than 30 comments and the workflow posts a duplicate. * URL-encode `ADO_ORG` and `ADO_PROJECT` in both the curl base URL and the JS link-back URL. ADO project names commonly contain spaces or reserved URL characters; the previous form would emit malformed request URLs in those cases. * Validate that `ISSUE_NUMBER` is strictly numeric BEFORE the workflow_dispatch path's `gh issue view` call, so malformed manual input fails fast with the explicit error rather than tunnelling through an unrelated `gh` failure. Signed-off-by: Yetkin Timocin <ytimocin@microsoft.com>
4 tasks
Yetkin Timocin (ytimocin)
requested review from
Tatsat (Tats) Mishra 🐉 (Tatsinnit) and
Copilot
April 28, 2026 18:28
Yetkin Timocin (ytimocin)
added a commit
to ytimocin/kubefleet
that referenced
this pull request
Apr 29, 2026
Address inline review comments on PR kubefleet-dev#527: * Gate the `labeled` event on `github.event.label.name == 'ado-sync'` so adding any unrelated label to an issue that already has `ado-sync` no longer re-triggers a sync. Closed/reopened keep the label-presence check because the action payload omits `label.name` there. * Paginate the `listComments` call before the link-back-marker dedupe check, otherwise the marker is missed when the issue has more than 30 comments and the workflow posts a duplicate. * URL-encode `ADO_ORG` and `ADO_PROJECT` in both the curl base URL and the JS link-back URL. ADO project names commonly contain spaces or reserved URL characters; the previous form would emit malformed request URLs in those cases. * Validate that `ISSUE_NUMBER` is strictly numeric BEFORE the workflow_dispatch path's `gh issue view` call, so malformed manual input fails fast with the explicit error rather than tunnelling through an unrelated `gh` failure. Signed-off-by: Yetkin Timocin <ytimocin@microsoft.com>
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
April 29, 2026 22:17
bda8ac7 to
9d9ccfa
Compare
Signed-off-by: Yetkin Timocin <ytimocin@microsoft.com>
Address inline review comments on PR kubefleet-dev#527: * Gate the `labeled` event on `github.event.label.name == 'ado-sync'` so adding any unrelated label to an issue that already has `ado-sync` no longer re-triggers a sync. Closed/reopened keep the label-presence check because the action payload omits `label.name` there. * Paginate the `listComments` call before the link-back-marker dedupe check, otherwise the marker is missed when the issue has more than 30 comments and the workflow posts a duplicate. * URL-encode `ADO_ORG` and `ADO_PROJECT` in both the curl base URL and the JS link-back URL. ADO project names commonly contain spaces or reserved URL characters; the previous form would emit malformed request URLs in those cases. * Validate that `ISSUE_NUMBER` is strictly numeric BEFORE the workflow_dispatch path's `gh issue view` call, so malformed manual input fails fast with the explicit error rather than tunnelling through an unrelated `gh` failure. Signed-off-by: Yetkin Timocin <ytimocin@microsoft.com>
Yetkin Timocin (ytimocin)
force-pushed
the
ci/sync-issues-to-ado
branch
from
May 1, 2026 17:40
9d9ccfa to
6b43309
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of your changes
This pull request introduces a new GitHub Actions workflow,
.github/workflows/sync-issues-to-ado.yml, that securely and automatically syncs approved GitHub issues to Azure DevOps (ADO) as work items. The workflow emphasizes security, least privilege, and supply-chain safety by using direct API calls and robust input validation. It only syncs issues labeled withado-syncby maintainers, and provides a manual trigger for ad-hoc syncing.Security and Trust Boundaries
ado-syncby maintainers are eligible for syncing. Manual syncs are also label-gated to prevent bypasses.syncjob declaresenvironment: issuesso secrets sit behind environment-level access approval per the secure-use guidance. The required-reviewers rule on that environment is what makes the gate non-decorative — see "Before first run" below.jq --arg,@htmlescaping, random-delimiter heredocs forGITHUB_OUTPUT).Supply-Chain and Permissions Hardening
actions/github-scriptto a full-length commit SHA.permissions: { issues: write }at workflow level. Splitting into two jobs so the ADO PAT and the GitHub-write token never coexist in one process is tracked in [Feature] Harden ado-sync workflow per secure-use guidance #680.Review feedback addressed (commit
bda8ac7f)labeledevents ongithub.event.label.name == 'ado-sync'so adding any other label to anado-syncissue no longer re-triggers a sync.listCommentsso the link-back marker is found even when an issue has >30 comments.ADO_ORGandADO_PROJECTin both the curl base URL and the JS link-back URL.ISSUE_NUMBERis strictly numeric before anygh issue viewcall on the manual-dispatch path.I have:
make reviewableto ensure this PR is ready for review.How has this code been tested
Locally tested with act:
-e test-issue-event.json— fake issue event payload-n— dry run (no containers actually started)--env GITHUB_REPOSITORY=...— overrides the repo guard so the job isn't skipped on a forkThe workflow has not yet run end-to-end against a real ADO instance. The first labelled issue post-merge is the first true e2e, so the configuration in "Before first run" must be in place before any issue gets labelled
ado-syncin production.Before first run (required configuration)
The job declares
environment: issues, so the secrets below should be configured on that environment (not just at repo level) so they inherit the environment's access-approval rule.Environment secrets to add to the
issuesenvironment (only names are listed; values are set in repo settings — never paste real values into a PR/issue/comment):ADO_PATADO_ORGANIZATIONADO_PROJECT[System.TeamProject]filter.ADO_AREA_PATHSystem.AreaPathvalue applied to new work items.ADO_ITERATION_PATHSystem.IterationPathvalue applied to new work items.The auto-provided
GITHUB_TOKEN(referenced as${{ github.token }}and implicitly used byactions/github-script) does not need to be added — it is issued per run.Repo configuration (no YAML, all in Settings):
issuesenvironment under Settings → Environments. Configure all five secrets above on it.issues(per the secure-use guidance). Without it, the environment gate is decorative — anyone with write access could trigger aworkflow_dispatchand reach the PAT.main, so aworkflow_dispatchfrom a feature branch cannot run a modified workflow that exfiltrates the PAT.ado-synclabel in the repo. The workflow gates on it; without the label no issue is syncable.ADO_PATrotation before its expiration.Bonus pre-flight verification:
ADO_PATauthenticates against ADO (one-shotcurlagainst_apis/projectsreturns 200) before labelling the first issue.Special notes for your reviewer
Follow-up hardening tracked in #680: job split for tighter
permissionsscoping, GitHub-App-vs-PAT evaluation for the ADO credential, andCODEOWNERSfor.github/workflows/.