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

[JENKINS-60245] Potential fix for @Library annotation in load()'d scripts #87

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

awittha
Copy link

@awittha awittha commented Nov 21, 2019

This is a potential fix for the issue described in JENKINS-60245. I call it a "potential" fix because while it seems to fix all the broken use-cases and cause no regressions, I am not sure if there is a more architecturally-sound means to accomplish the same ends.

Please see the JIRA issue for a complete description of the problem.

These changes add a String scope to LibrariesAction, and attach one action to a build per loaded script.

When recording shared libraries that were mentioned in a @Library annotation, the script being processed is used as the scope of the LibrariesAction. This enables the plugin to know that it should index the contents of @Library annotations in newly-loaded scripts.

When processing libraries to actually add their resources to the classpath, every LibrariesAction for the build is iterated over.

This allows scripts loaded with the load(...) step to add shared libraries with the @Library(...) annotation.

I had to update some existing unit tests, but did not write a regression test for the new behavior. If this implementation of a solution to JENKINS-60245 is determined to be generally-sound & on-track for merging into the plugin, I will write such a test.

* @param execution a running build (possibly newly started, possibly resumed)
* @param libraries aggregated entries from all encountered {@link Library#value} (will be empty if {@link Library} is never used at all); an implementation should remove entries it “claims”
* @return a possibly empty list of additions
* @throws Exception for whatever reason (will fail compilation)
*/
public abstract @Nonnull List<Addition> add(@Nonnull CpsFlowExecution execution, @Nonnull List<String> libraries, @Nonnull HashMap<String, Boolean> changelogs) throws Exception;
public abstract @Nonnull List<Addition> add(@Nullable String scope, @Nonnull CpsFlowExecution execution, @Nonnull List<String> libraries, @Nonnull HashMap<String, Boolean> changelogs) throws Exception;
Copy link
Author

Choose a reason for hiding this comment

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

New add(...) method added to the ClasspathAdder interface, to allow for scoping the source of an addition.

}

LibrariesAction(String scope, List<LibraryRecord> libraries) {
this.scope = scope;
Copy link
Author

Choose a reason for hiding this comment

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

New constructor & field added to LibrariesAction to allow recording of "scope" - what source file the libraries in this LibrariesAction are from.

LibrariesAction action = null;

for( LibrariesAction laction : build.getActions( LibrariesAction.class ) ) {
if( laction.getScope() != null && laction.getScope().equals( scope ) ) {
Copy link
Author

Choose a reason for hiding this comment

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

Previously, as there was only ever one LibrariesAction per build, if it was present, it was concluded that this was a resumed build and that action could be used.

Now, there may be multiple actions so we must find the one whose scope equals the scope passed into this add invocation.

break;
} else if( laction.getScope() == null ) {
// generic LibrariesAction may be overridden later if there's a perfect match.
action = laction;
Copy link
Author

Choose a reason for hiding this comment

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

It is possible that a build was suspended before these code changes landed, in which case the "right" LibrariesAction will have a null scope.

for (URL u : retrieve(record.name, record.version, retrievers.get(record.name), record.trusted, record.changelog, listener, build, execution, record.variables)) {
additions.add(new Addition(u, record.trusted));
if( librariesAdded.size() > 0 ) {
build.addAction(new LibrariesAction(new ArrayList<>(librariesAdded.values())));
Copy link
Author

@awittha awittha Nov 21, 2019

Choose a reason for hiding this comment

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

Avoid adding a LibrariesAction with 0 library definitions in it.

This feels more right to me - I couldn't figure any solid reason for adding a LibrariesAction with no definitions. Is there one? I am not married to this particular semantic change; it was just instinct to not add a record of nothing.

@dwnusbaum
Copy link
Member

Thanks for the PR! I'm not totally sure about this, here are a few of the immediate questions that came to mind:

  • Would this also work for a shared library that references another shared library via @Library, or is this only for scripts loaded via the load step?
  • With this change, if there is more than one load step, and each loaded script loads the same shared library, would we have multiple instances of the shared library loaded in the Pipeline?
  • In the use case you give in JENKINS-60245, why not just drop the load step entirely and have your Jenkinsfile reference the library? I am guessing you simplified your actual use case?

@jglick
Copy link
Member

jglick commented May 23, 2022

As of #172 most of the code in this plugin has been moved to another plugin repository so this PR must be closed. If this change is still needed, please

git clone https://github.com/jenkinsci/pipeline-groovy-lib-plugin
cd pipeline-groovy-lib-plugin
git checkout -b JENKINS-60245
git pull https://github.com/awittha/workflow-cps-global-lib-plugin JENKINS-60245

resolve any merge conflicts, and file a fresh PR on the new repository. Be sure to paste a link to this old PR to enable bidirectional navigation.

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.

3 participants