-
Notifications
You must be signed in to change notification settings - Fork 741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include assets directly in GHRelease #977
Include assets directly in GHRelease #977
Conversation
Resolves hub4j#528 Instead of doing a separate request to fetch the assets associated with a release this keeps a local list of the assets that are part of the list releases endpoint. See https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#list-releases
I don't know a better name for this, and I also don't know whether this should be an option or not. The life cycle tests use the feature that retrieving the assets from a release actually does a roundtrip to Github and sends another request. This indicates that re-purposing `getAssets()` to be the cached access might cause problems on consumers that potentially rely on this assumption, too.
@bitwiseman pinging you because I cannot request you as reviewer 😉 @johnoliver is this what you had in mind when opening #528 ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a tough problem.
I think this change results in more correct behavior, but it also a breaking change in terms of the behavior of the existing method.
Someone expecting getAssets()
to always return the up-to-date list of assets is going to get a very unpleasant surprise when this change goes in.
I would suggest you create a new method instead of modifying the old one (at least for now). Maybe call it getCachedAssets()
and make it @Deprecated @Preview
with comments explaining what is going on. Also make getAssets()
@Deprecated
(but not preview) with an explanation this the method is still usable but that the behavior will change in a future version.
That would unlock the behavior you want but not break existing users.
Add '@Deprecation' and '@Preview' annotations to make the changes backwards compatible and prepare for a transition to the cached behavior as default. This explicitly leaves the variant for re-fetching assets under a different name.
* @throws IOException | ||
* the io exception | ||
*/ | ||
public List<GHAsset> fetchAssets() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left this in as I think this is a quite handy featuer to have (easily run queries to be up to date, if required). If you would rather see this removed please let me know. In that case, the test cases should also be revisitied to cover the same use case with just the new, cached behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable. But since we're fetching, let's return a PagedIterable
for more flexibility. This also means it makes sense to use the list*
verb like we do on all other methods that return PagedIterable
.
public List<GHAsset> fetchAssets() throws IOException { | |
public PagedIterable<GHAsset> listAssets() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great. Some additional discussion and changes. After this we should be good to go.
Thanks!
} | ||
|
||
private void deleteAsset(GHRelease release, GHAsset asset) throws IOException { | ||
asset.delete(); | ||
assertEquals(0, release.getAssets().size()); | ||
assertEquals(0, release.getCachedAssets().size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems strange. If the asset was cached in the release before deletion, it should be there after was well - that cache shouldn't change. Perhaps add an assert that the asset if present in getCachedAssets()
before deletion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The confusing part here might be that we're still dealing with the very first GHRelease
from this test - even before we actually created an asset for it.
I'll take another look at the tests and see if I can add something in addition to make this clearer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I get it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to figure out how this whole wiremock setup works - and gave up 😕 To be able to add an assertion like the one you mentioned I'd need to re-fetch the intermediate state of the release, e.g.,
// test that asset upload works
GHAsset asset = uploadAsset(release);
// get new "snapshot" of the release with cached asset
GHRelease releaseWithAsset = repository.getReleases().get(0);
// update the asset, check before and after with the new snapshot
updateAsset(releaseWithAsset, asset);
// repeat same pattern for 'delete'
However, it looks like the wiremocks do not account for additional calls to repository.getReleases().get(0)
I suppose, at least they obviously don't return the new state of the release...
If I should change something in these tests I'd appreciate your help... 🙄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to make it easier to re-record tests, but in the meanwhile here's the instructions:
https://github.com/hub4j/github-api/blob/master/CONTRIBUTING.md#generating-a-new-snapshot
The instructions could be better too. 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it is okay to leave this as it is.
* @throws IOException | ||
* the io exception | ||
*/ | ||
public List<GHAsset> fetchAssets() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable. But since we're fetching, let's return a PagedIterable
for more flexibility. This also means it makes sense to use the list*
verb like we do on all other methods that return PagedIterable
.
public List<GHAsset> fetchAssets() throws IOException { | |
public PagedIterable<GHAsset> listAssets() throws IOException { |
*/ | ||
@Deprecated | ||
@Preview | ||
public List<GHAsset> getCachedAssets() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API design question for you: Thinking about it a bit more, what do you think about using a bare property names for field access? I don't think this needs changing for this change, but I'm thinking about what this should look like in v2.
public List<GHAsset> assets() {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would really like this kind of simplified naming 👍 🤓
public List<GHAsset> getAssets() throws IOException { | ||
Requester builder = owner.root.createRequest(); | ||
return fetchAssets(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given we change the name and return type of fetchAssets()
:
return fetchAssets(); | |
return listAssets().toList(); |
@@ -45,18 +45,20 @@ public void testCreateRepository() throws IOException { | |||
|
|||
private void updateAsset(GHRelease release, GHAsset asset) throws IOException { | |||
asset.setLabel("test label"); | |||
assertEquals("test label", release.getAssets().get(0).getLabel()); | |||
assertEquals("test label", release.fetchAssets().get(0).getLabel()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the test pointing to the deprecated method since it wraps the new method and we want to show the behavior hasn't changed.
assertEquals("test label", release.fetchAssets().get(0).getLabel()); | |
assertEquals("test label", release.getAssets().get(0).getLabel()); |
Description
Resolves #528
Instead of doing a separate request to fetch the assets associated with
a release this keeps a local list of the assets that are part of the
list releases endpoint.
See https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#list-releases
The first commit c74fbbe expectedly fails at
as the call to
release.getAssets()
not returns the cached content instead of doing another request.github-api/src/test/java/org/kohsuke/github/LifecycleTest.java
Lines 56 to 64 in 3a11b7c
Therefore, the second commit d881bf6 brings back the previous functionality as
fetchAssets()
. I don't know a better name for this, and I also don't know whether this should be an option or not.The life cycle tests use the feature that retrieving the assets from a release actually does a roundtrip to Github and sends another request. This indicates that re-purposing
getAssets()
to be the cached access might cause problems on consumers that potentially rely on this assumption, too.