Skip to content
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

✨ Get staging profile task #62

Merged
merged 4 commits into from
Mar 8, 2021

Conversation

ryandens
Copy link
Contributor

@ryandens ryandens commented Feb 18, 2021

Closes #60

Documentation Updates

I think we should add an update to the "Tasks" section of the migration guide to say something like

./gradlew getStagingProfile

./gradlew retrieveSonatypeStagingProfile

This reflects the main difference between the previous plugin project and this one: tasks are on a per NexusRepsitory basis, including the RetrieveStagingProfile task.

Summary of changes

First adds a new AbstractNexusStagingRepositoryTask subclass called RetrieveStagingProfile. we register a new RetrieveStagingProfile task for each NexusRepository registered in the plugin's extension. This enables users to run
./gradlew retrieve<NEXUS_REPOSITORY_NAME>StagingProfile and see the staging profile ID for the repository in stdout.

This was initially as far as I was planning on going with this, but something @szpak mentioned in issue #60 caught my attention

Or maybe there should be also an @output field set to allow others to read it (but I'm not sure why anyone would like to consume that)

After reading this, it struck me that we wouldn't want there to be inconsistencies between how GetStagingProfile gets the staging profile and how InitializeNexusStagingRepository gets the staging profile. So, I went about a small refactor of the plugin to remove the responsibility of figuring out the staging profile id from InitializeNexusStagingRepository and instead make it a required input. Then, I configured InitializeNexusStagingRepository to depend on the GetStagingProfile which now has all the logic for getting the staging profile ID, outputting it to stdout, storing the ID in a file in the build directory, and managing the optimization of not doing the API lookup if the staging profile id is provided via configuration.

This not only has benefits for code re-use, but it also helps those who don't configure the stagingProfileId ever. Since we output the staging profile ID to an artifact, it can be cached and reused on subsequent builds which decreases the configuration burden on the user while still giving them access to this performance optimization.

I know changing InitializeNexusStagingRepository was not technically in the scope of what was discussed in #60 so if you would like me to remove it from the scope of this change I'd be happy to. But, it seemed to me like refactoring InitializeNexusStagingRepository was the responsible thing to do as I was introducing some logic duplication around how this plugin gets the staging profile id.

Update on 2/27/21: After discussion, it was deemed that this refactor was problematic due to the conflicting nature of the different use cases of the InitializeNexusStagingRepository task and the diagnostic task to retrieve the staging profile

Possible other tasks

Another thought that occurred to me was adding a task called getStagingProfiles or getAllStagingProfiles which is simply an alias for executing get<NEXUS_REPOSITORY_NAME>StagingProfile on each configured NexusRepository. I ultimately decided it was not worthwhile/might cause confusion but I'm willing to reconsider.

Testing gaps?

After writing up this pull request description, I realized my implementation for storing the staging repository ID was flawed, as I at first would overwrite the file storing the staging profile ID every time a new GetStagingProfile was run, which could lead to confusing results with multiple NexusRepository destinations. The existing tests didn't catch it because there were no tests that published to two different repositories at the same time. I had to make some tweaks to the helper methods to accomplish this test, but I'm super open to feedback on how this was tested. Perhaps it would be better as a unit test than a compatTest?

Copy link
Contributor

@szpak szpak left a comment

Choose a reason for hiding this comment

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

Really informative PR description, thanks!

I went through the code and in general I like it. Chaining tasks makes sense, but there is one side effect related to logging. I put some remarks inline.

I also requested e2e tests on your PR.

@ryandens ryandens requested a review from szpak February 28, 2021 15:41
Copy link
Member

@marcphilipp marcphilipp left a comment

Choose a reason for hiding this comment

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

Why don't we use the new task to retrieve the staging profile id for the initialize task?

/**
* Diagnostic task for retrieving the [NexusRepository.stagingProfileId] for the [packageGroup] from the provided [NexusRepository] and logging it
*/
@Incubating
Copy link
Member

Choose a reason for hiding this comment

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

@szpak Not sure if we should use this annotation. WDYT?

Copy link
Contributor

@szpak szpak Mar 2, 2021

Choose a reason for hiding this comment

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

Personally, I like to use @Incubating for the new tasks/features to gather feedback and possibly have a clear way to fix spotted issues even in a non-backward compatible way in the following release. However, you don't like the "beta" status of that feature or just a Gradle annotation?

Copy link
Member

Choose a reason for hiding this comment

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

Ok, fine with me but we should have some common understanding when to do this. IIUC you'd like to do this for all new features. Is that correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be safe, but maybe it would be to defensive, as we - in general - do not expose API to others (at least, it is not the main goal of that extension). How does it look like in JUnit? Are you satisfied with the strategy adopted there?

@szpak
Copy link
Contributor

szpak commented Mar 2, 2021

Why don't we use the new task to retrieve the staging profile id for the initialize task?

@marcphilipp I asked the PR's author about that a comment earlier - see my reasoning. It simplifies the general construction and we eventually still use the common logic from the client.

@marcphilipp marcphilipp changed the title ✨ Get staging profile task ✨ Get staging profile task Mar 6, 2021
/**
* Diagnostic task for retrieving the [NexusRepository.stagingProfileId] for the [packageGroup] from the provided [NexusRepository] and logging it
*/
@Incubating
Copy link
Member

Choose a reason for hiding this comment

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

Ok, fine with me but we should have some common understanding when to do this. IIUC you'd like to do this for all new features. Is that correct?

* helper method for get getting a [ExtensionContext.Store] specific to a test method
*/
private fun getStore(context: ExtensionContext): ExtensionContext.Store {
return context.getStore(ExtensionContext.Namespace.create(javaClass, context.requiredTestMethod))
Copy link
Member

Choose a reason for hiding this comment

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

There's no need to add the test method to the namespace since the extension context is already scoped to the method level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I couldn't remember the rules around this so I went looking in the user guide and derived it from this example: https://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks-before-after-execution - but fixed!

Copy link
Member

Choose a reason for hiding this comment

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

Good point! That example should indeed be simplified.

@szpak szpak merged commit f3c24a7 into gradle-nexus:master Mar 8, 2021
@szpak
Copy link
Contributor

szpak commented Mar 8, 2021

Thanks @ryandens for your PR (and patience ;-) ). It will be a part of 1.1.0.

@ryandens
Copy link
Contributor Author

ryandens commented Mar 8, 2021

Awesome, thanks for accepting my contribution and working through the feedback with me! Hoping this makes it easier for other folks to adopt this plugin 😄

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.

✨ Feature Request: GetStagingProfileTask
4 participants