backstage / backstage/backstage
GithubUrlReader: support reading GitHub release assets as UrlReader sources
- Dominant language
- TypeScript
- Stars
- 34.4k
- Forks
- 7.6k
- Avg merge
- 8h 57m
- Merged PRs (30d)
- 50
Description
### 📜 Issue Labels
- [x] Please familiarize yourself with the issue labels used in this project: [LABELS.md](https://github.com/backstage/backstage/blob/master/LABELS.md)
### 🔎 Search Terms
`GithubUrlReader release`, `release asset url reader`, `read release asset`, `getGithubFileFetchUrl releases` — no existing issues or PRs found.
### 🗃️ Project Area
Core Framework
### 🔖 Need
It is common to publish versioned, immutable files as GitHub **release assets** (tag-scoped, not committed to the default branch). It would be useful to reference such an asset anywhere Backstage accepts a `UrlReader` source (for example a catalog `$text` placeholder), reusing the GitHub credentials Backstage already holds.
Today `GithubUrlReader` (via `getGithubFileFetchUrl` in `@backstage/integration`) resolves only repository *content* URLs: `filepathtype` must be `blob`, `raw`, or `tree`. A release-asset URL such as `https://github.com///releases/download//` is none of those — `parseGitUrl` (git-url-parse) returns an empty `filepathtype` (and no `ref`) for it — so `getGithubFileFetchUrl` rejects it and throws `Invalid GitHub URL or file path` (re-thrown as `Incorrect URL: …`). So release assets cannot be used as a `UrlReader` source.
This would help anyone who distributes versioned files via releases rather than committing them into the repo tree.
### 📝 Proposal
Let the GitHub integration read **release assets** using the existing credentials (token / GitHub App), so a release-download URL works anywhere a `UrlReader` source is accepted, e.g.:
```
$text: https://github.com/acme/repo/releases/download/v1.2.0/artifact.yaml
```
Sketch: extend `getGithubFileFetchUrl` / `GithubUrlReader.readUrl` to recognize release-asset URLs, both the browser form `.../releases/download//` and/or the API form `.../repos///releases/assets/`, and fetch via `GET /repos/{owner}/{repo}/releases/assets/{id}` with `Accept: application/octet-stream`, using the existing `GithubCredentialsProvider`. Resolving `/` to an asset id is one extra call to `GET /repos/{owner}/{repo}/releases/tags/{tag}`.
Relevant code:
- `packages/integration/src/github/core.ts` (`getGithubFileFetchUrl` validation)
- `packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts`
Observed on Backstage 1.42.x.
### 🔄 Alternatives
- **Custom `UrlReader`** that recognizes release URLs and authenticates to GitHub. Works, but every adopter has to build and maintain it, duplicating the auth `GithubUrlReader` already implements.
- **Commit the file into the repo tree** (blob/raw) and reference that. Works with today's reader, but pollutes git history and loses the tag-scoped immutability of a release asset.
- **Generic `FetchUrlReader`** against the release download URL. Fails for private repos: it cannot authenticate, whereas `GithubUrlReader` already holds the right credentials.
### Have you read the Code of Conduct?
- [x] I have read the [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)
### Are you willing to submit a PR?
Undecided — happy to help or collaborate on a PR if this aligns with the integration's direction.
Contributor guide
Research direction
Start by reading getGithubFileFetchUrl in packages/integration/src/github/core.ts and GithubUrlReader in packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts. Trace how existing credentials and content URLs are handled, then define support for the release-download and/or API asset forms. Done means authenticated release assets can be read as UrlReader sources, including the private-repository case described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, typescript
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100