Skip to content

GitHub: create a GitHub-backed list from a repository #73

Closed

Description

@Adron

Product behaviour (/help/lists)

The new-list flow has two tabs: Local List and GitHub-backed List. On the GitHub tab:

  • pick a repository you have access to;
  • enter a list title (defaults to the repo name);
  • optionally set a parent list;
  • toggle Public list.

GitHub-backed lists show a GitHub icon and sync issues from the repo. Rows map to issues — add a row creates an issue, edit updates it, delete closes it.

Prerequisite: GitHub connected with the Issues scope. An account linked for sign-in only needs "Reconnect for GitHub Issues".

Acceptance criteria

  • A GitHub-backed tab in the new-list flow with a repo picker (grouped by org, paginated).
  • Title defaults to the repo name; parent list and public toggle available.
  • ListSummary.source/githubRepo/githubRepoPrivate are modelled and a GitHub icon marks such lists.
  • Missing Issues scope is detected up front and offers the reconnect handoff rather than failing at create.

Activity

  1. Adron commented on Sep 16, 2026

    @Adron
    MemberAuthor

    Live probe results from the service layer (#72 / PR #142)

    ⚠️ Correction to the epic's premise: the test account IS GitHub-linked

    GET /api/user/identities shows provider github, username InterlinedListMessenger. The 200 [] from /repos and /orgs means that GitHub account owns no repos and joins no orgs — not that nothing is linked. So:

    • The genuinely-unlinked response shape is still unobserved.
    • Link state must come from /api/user/identities (GetGitHubLinkStateAsync → GitHubLinkState), never from an empty collection. Inferring "not linked" from [] would show a Connect prompt to an already-connected user.
    • ClassifyGitHubFailure / GitHubFailureReason exist as a backstop, with NotLinked flagged unverified.

    All nine endpoints, live

    Endpoint Status Shape
    GET /repos 200 bare array, 0 items
    GET /repos?org=github 200 559 items in one array
    GET /repos?org=dotnet 200 278
    GET /repos?org=microsoft | google | apache 200 exactly 2000 each
    GET /repos?org=Adron (a user) 404 not_found
    GET /orgs 200 bare array, 0 items — item shape never observed
    GET /issues (no repo, no default) 400 "Repository required. Set default repo in Settings or pass repo parameter (owner/repo)."
    GET /issues?repo=o/r&state=all 200 bare array, 13 items
    GET /issues?…&state=OPEN 422 validation_failed — state is case-sensitive
    GET /repos/{o}/{r}/assignees 200 bare array, capped at 30
    GET /repos/{o}/{r}/labels 200 bare array, capped at 30
    GET /repos/{o}/{r}/next-issue-number 200 {"nextNumber":14}; 1 for an issue-less repo

    POST /issues, the PATCH, and the comments endpoint were not called — they write to real GitHub repositories.

    #73 specifically: no client paging needed, but an ?org= is

    The epic said "documented as fully paginated; implement paging". Wrong in both directions. The server walks GitHub's pages itself and returns the complete set in one bare array (559 for ?org=github, well past GitHub's 100/page ceiling). There is no envelope, no Link header, and no page/per_page parameter — ?page=2&per_page=5 changed nothing. Only ?org= exists.

    But there's an apparent server cap of 2000 (three large orgs each returned exactly 2000; aws returned a natural 552), so the repo picker should show a "first 2000" hint rather than implying completeness.

    Also: /repos returns a slim server projection, not GitHub's repo object — exactly {full_name, name, private, owner_login}, uniform across all 2837 items checked.

    Conversely, issues / labels / assignees are stuck on GitHub's first 30 with no way to page further. That's a real limitation for #75.

    #76 specifically: ?link=true is load-bearing

    /api/auth/github/authorize requests only scope=user:email read:user. ?link=true is what requests repo read:org — i.e. the Issues scope. A ?scope= of your own is ignored, and an arbitrary redirect_uri is rejected.

    Separately, /api/auth/github/status carries manageOrgAccessUrl — the documented fix for missing org repos that a reconnect cannot solve (org-level third-party app approval). #76 should surface that as a distinct action, not just "reconnect".

    #74/#75: pull requests arrive as issues

    12 of 13 items from a real repo with state=all were pull requests. GitHubIssue.IsPullRequest handles it — filter or label them, or a GitHub-backed list will silently fill with PRs.

  2. Adron commented on Sep 16, 2026

    @Adron
    MemberAuthor

    Implemented in #175 — work continues in the PR from here.

    The GitHub-backed tab ships as a self-contained NewListTabs control (5 lines of hosting in the contended ListsView.xaml, nothing added to ListsViewModel), with the repo picker, title-defaults-to-repo-name, parent list, Public toggle, and a GitHub badge on backed lists fed by a one-request index. Two of the issue's premises turned out wrong live: /api/github/repos needs no client paging (the whole set arrives in one bare array) but does need an ?org=, and exactly 2000 rows is a server truncation — now confirmed on six large orgs, so the picker says "first 2,000" rather than implying completeness.

    "Detect the missing Issues scope up front" can't be met literally: no endpoint reports scopes, so the panel says so plainly and instead gates on real link state from /api/user/identities, keeps the reconnect handoff always visible, and distinguishes "reconnect" from "grant organization access". The GitHub-backed create itself was deliberately never executed — it would wire a real repository to a real list — though its 400 contract was verified without creating anything.

  3. added 2 commits that reference this issue on Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Table stakesarea:githubArea: githubarea:listsArea: listsparityWeb/API feature-parity work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions