Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@babakks
Copy link
Member

@babakks babakks commented Oct 31, 2025

Fixes #11272

Notes for reviewers

  • Since the GraphQL query has to be different based on the host's support for immutable releases, I had three options for implementation:

    1. plain text query compilation (i.e. dynamically adding the immutable field if applicable)
    2. dynamic handling of two strongly-typed query types in the same function
    3. duplicating the strongly-typed query function into two separate ones

    I decided to go with the 3rd option since it's more readable and simpler to cleanup (i.e. by just deleting the duplicated function) while keeping our strongly-typed query approach. The cleanup should happen after all covered GHES versions fully support immutable releases. This decision is based on the assumption that there'll be no new Release-level fields/features like this. I might be wrong, in which case I believe it'd be best to go with the first approach (plain text queries) which will make room for adding more fields as we go. Please comment if that's the case and I'll take care of it. Needless to mention the 2nd option is super complex with basically duplicating everything in a single function; harder to read/maintain and aesthetically unpleasant.

  • Another assumption here, is that new GHES versions will be shipped with immutable releases. So at some point we can comeback and clean up the dual behaviour and bring the simple code back. As I checked, the latest GHES 3.18 does not support immutable releases. So I guess we should at least wait until 3.18 goes EOL. If this is not the right assumption, please let me know. This'll be another reason for going with plain text queries.

A/C Verification

Given I'm using gh against github.com
When I run gh release list -R OWNER/REPO
Then I see no changes in the output structure

Confirmed. The isImmutable field is only visible in JSON mode.

Given I'm using gh against github.com
When I run gh release list -R OWNER/REPO --json name,isImmutable
Then I see the isImmutable field is correctly assigned

Confirmed: (I enabled immutable releases on this before making the second release)

$ gh release list -R gh-babakks/foo --json name,isImmutable | jq 
[
  {
    "isImmutable": false,
    "name": "title"
  },
  {
    "isImmutable": true,
    "name": "v1.1.2"
  }
]

Given I'm using gh against a GHES host that does not support immutable releases
When I run gh release list -R OWNER/REPO --json name,isImmutable
Then I see the isImmutable field is set to false for all entries

Confirmed by testing against GHES 3.18:

$ GH_HOST=<HOST> gh release list -R gh-babakks/foo --json name,isImmutable | jq
[
  {
    "isImmutable": false,
    "name": "title"
  }
]

Given I'm using gh against a GHES host that supports immutable releases
When I run gh release list -R OWNER/REPO --json name,isImmutable
Then I see the isImmutable field is correctly assigned

Unable to confirm since we yet to have such a GHES version.

@babakks babakks linked an issue Oct 31, 2025 that may be closed by this pull request
@babakks babakks requested review from a team and BagToad October 31, 2025 20:26
@babakks babakks marked this pull request as ready for review October 31, 2025 20:26
@babakks babakks requested a review from a team as a code owner October 31, 2025 20:26
Copilot AI review requested due to automatic review settings October 31, 2025 20:26
@babakks babakks requested a review from bdehamer October 31, 2025 20:28
Comment on lines 41 to 61
func fetchReleases(httpClient *http.Client, repo ghrepo.Interface, limit int, excludeDrafts bool, excludePreReleases bool, order string, releaseFeatures fd.ReleaseFeatures) ([]Release, error) {
// TODO: immutableReleaseFullSupport
// This is a temporary workaround until all supported GHES versions fully
// support immutable releases, which would probably be when GHES 3.18 goes
// EOL. At that point we can remove this if statement.
//
// Note 1: This could be have been done differently by using dual two
// separate query types or even using plain text/string queries. But, both
// would require us to refactor them back in the future, to the single,
// strongly-typed query approach as it was before. So, duplicating the entire
// function for now seems like the lesser evil, with a quicker and less risky
// clean up in the near future.
//
// Note 2: We couldn't use GraphQL directives like `@include(condition)` or
// `@skip`(condition) here because if the field doesn't exist on the schema
// then the whole query would still fail regardless of the condition being
// met or not.
if !releaseFeatures.ImmutableReleases {
return fetchReleasesWithoutImmutableReleases(httpClient, repo, limit, excludeDrafts, excludePreReleases, order)
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Explained the rationale here as well.

Copy link
Contributor

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 adds support for immutable releases by implementing feature detection to check if the GitHub host supports the immutable field on releases. The implementation includes a temporary workaround for GHES versions that don't support this feature yet.

Key Changes:

  • Adds ReleaseFeatures detection to identify whether a GitHub host supports immutable releases
  • Implements dual code paths: one that queries the immutable field and another that doesn't, based on feature detection
  • Updates tests to cover both supported and unsupported scenarios for immutable releases

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/cmd/release/list/list.go Integrates feature detection for immutable releases into the list command
pkg/cmd/release/list/http.go Adds conditional GraphQL queries based on immutable release support and creates temporary fallback function
pkg/cmd/release/list/list_test.go Expands test coverage with separate test cases for supported and unsupported immutable releases
internal/featuredetection/feature_detection.go Implements ReleaseFeatures() method to detect immutable release support
internal/featuredetection/feature_detection_test.go Adds comprehensive tests for release feature detection
internal/featuredetection/detector_mock.go Adds mock implementations for testing with/without immutable release support

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
@bdehamer
Copy link
Contributor

bdehamer commented Oct 31, 2025

This decision is based on the assumption that there'll be no new Release-level fields/features like this

There are no plans for adding additional fields to the Release object at this time.

Another assumption here, is that new GHES versions will be shipped with immutable releases.

Yes. GHES 3.19 will be the first version which returns the immutable field in the GQL Release object (though it will always be "false"). GHES 3.20 will be the first version in which users can actually enable immutable releases on their repositories..

Copy link
Contributor

@bdehamer bdehamer left a comment

Choose a reason for hiding this comment

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

LGTM!

@babakks babakks merged commit 895c314 into trunk Nov 4, 2025
11 checks passed
@babakks babakks deleted the babakks/add-isimmutable-to-release-list branch November 4, 2025 12:43
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Nov 6, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.82.1` -> `v2.83.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.83.0`](https://github.com/cli/cli/releases/tag/v2.83.0): GitHub CLI 2.83.0

[Compare Source](cli/cli@v2.82.1...v2.83.0)

#### What's Changed

##### ✨ Features

- Add `isImmutable` to `release list` JSON output by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12064](cli/cli#12064)
- `gh agent-task create`: support `--custom-agent`/`-a` flag by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12068](cli/cli#12068)
- πŸ’‘ (gh repo delete) Add warning when `--yes` is ignored without a repository, Closes: [#&#8203;12033](cli/cli#12033) by [@&#8203;Shion1305](https://github.com/Shion1305) in [#&#8203;12039](cli/cli#12039)
- feat: implement gh `pr revert` by [@&#8203;lucasmelin](https://github.com/lucasmelin) in [#&#8203;8826](cli/cli#8826)

##### πŸ› Fixes

- fix(gist): add support for editing & viewing large files  by [@&#8203;luxass](https://github.com/luxass) in [#&#8203;11761](cli/cli#11761)
- Fix gh attestation verify to work when Public Good Instance of Sigstore is unavailable by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;11989](cli/cli#11989)

##### πŸ“š Docs & Chores

- chore: add basic linters by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12084](cli/cli#12084)
- CI: Update lint govulncheck to use source mode by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12089](cli/cli#12089)
- chore: add `workflow_dispatch` to govulncheck triggers by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12085](cli/cli#12085)
- Exclude `third-party` from Golangci-lint formatting paths by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12058](cli/cli#12058)
- Apply `go fix` to remove deprecated `// +build` tags by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12056](cli/cli#12056)
- Bump Golangci-lint to `v2.6.0` by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12049](cli/cli#12049)
- Mention `pr checks` in `run list` docs by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12050](cli/cli#12050)
- Fix typo in comment for `gh issue develop` branch checkout command by [@&#8203;jonzfisher](https://github.com/jonzfisher) in [#&#8203;12042](cli/cli#12042)
- Use "release" sentinel value for release attestation verification by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;11991](cli/cli#11991)
- Improve docstring for release-create by [@&#8203;bdehamer](https://github.com/bdehamer) in [#&#8203;11945](cli/cli#11945)
- Improve `api` command docs around `--input` and `--field` by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12062](cli/cli#12062)
- Fix `--interval` flags docs in `gh pr checks` by [@&#8203;2003Aditya](https://github.com/2003Aditya) in [#&#8203;12053](cli/cli#12053)

##### :dependabot: Dependencies

- Bump Go to 1.25.3 by [@&#8203;github-actions](https://github.com/github-actions)\[bot] in [#&#8203;11926](cli/cli#11926)
- chore(deps): bump github.com/cli/go-gh/v2 from 2.12.2 to 2.13.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12095](cli/cli#12095)
- Update Go toolchain version to 1.24.9 by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12054](cli/cli#12054)
- chore(deps): bump golang.org/x/text from 0.29.0 to 0.30.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;11973](cli/cli#11973)
- chore(deps): bump golang.org/x/crypto from 0.42.0 to 0.43.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;11974](cli/cli#11974)
- chore(deps): bump actions/upload-artifact from 4 to 5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12031](cli/cli#12031)
- chore(deps): bump actions/download-artifact from 5 to 6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12032](cli/cli#12032)
- chore(deps): bump github.com/rivo/tview from 0.0.0-20250625164341-a4a78f1e05cb to 0.42.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12000](cli/cli#12000)
- chore(deps): bump goreleaser/goreleaser-action from 6.3.0 to 6.4.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;11509](cli/cli#11509)
- chore(deps): bump mislav/bump-homebrew-formula-action from 3.4 to 3.6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;11750](cli/cli#11750)

#### New Contributors

- [@&#8203;lucasmelin](https://github.com/lucasmelin) made their first contribution in [#&#8203;8826](cli/cli#8826)
- [@&#8203;jonzfisher](https://github.com/jonzfisher) made their first contribution in [#&#8203;12042](cli/cli#12042)
- [@&#8203;2003Aditya](https://github.com/2003Aditya) made their first contribution in [#&#8203;12053](cli/cli#12053)

**Full Changelog**: <cli/cli@v2.82.1...v2.83.0>

</details>

---

### Configuration

πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

β™» **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

πŸ”• **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNjkuMyIsInVwZGF0ZWRJblZlciI6IjQxLjE2OS4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
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.

Include isImmutable in release list

4 participants