From 166e4ad1ef46f9b45a739a95b9b4131b3dd885c1 Mon Sep 17 00:00:00 2001 From: Gavin Mogan Date: Sun, 4 Aug 2024 17:00:44 -0700 Subject: [PATCH 1/4] images:/ to images: (#1206) Co-authored-by: Mark Waite --- README.adoc | 88 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/README.adoc b/README.adoc index b35fec2fe9..548b5924fa 100644 --- a/README.adoc +++ b/README.adoc @@ -227,7 +227,7 @@ withCredentials([gitUsernamePassword(credentialsId: 'my-credentials-id', [#using-repositories] === Repositories -image:/images/git-repository-configuration.png[Repository Configuration] +image:images/git-repository-configuration.png[Repository Configuration] The git plugin fetches commits from one or more remote repositories and performs a checkout in the agent workspace. Repositories and their related information include: @@ -348,7 +348,7 @@ JGit becomes available throughout Jenkins once it has been enabled. [#global-configuration] === [[GitPlugin-Configuration]]Global Configuration -image:/images/git-global-configuration.png[Global Configuration] +image:images/git-global-configuration.png[Global Configuration] In the `Configure System` page, the Git Plugin provides the following options: @@ -473,7 +473,7 @@ See link:https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks["Customizing G [#repository-browser] === Repository Browser -image:/images/git-repository-browser.png[Repository Browser] +image:images/git-repository-browser.png[Repository Browser] A Repository Browser adds links in "changes" views within Jenkins to an external system for browsing the details of those changes. The "Auto" selection attempts to infer the repository browser from the "Repository URL" and can detect cloud versions of GitHub, Bitbucket and GitLab. @@ -483,7 +483,7 @@ Repository browsers include: [#assemblaweb-repository-browser] ==== AssemblaWeb -image:/images/git-repository-browser-assemblaweb.png[Assembla Repository Browser] +image:images/git-repository-browser-assemblaweb.png[Assembla Repository Browser] Repository browser for git repositories hosted by link:https://www.assembla.com/home[Assembla]. Options include: @@ -497,7 +497,7 @@ Assembla Git URL:: [#fisheye-repository-browser] ==== FishEye -image:/images/git-repository-browser-fisheye.png[FishEye Repository Browser] +image:images/git-repository-browser-fisheye.png[FishEye Repository Browser] Repository browser for git repositories hosted by link:https://www.atlassian.com/software/fisheye[Atlassian Fisheye]. Options include: @@ -511,7 +511,7 @@ URL:: [#kiln-repository-browser] ==== Kiln -image:/images/git-repository-browser-kiln.png[Kiln Repository Browser] +image:images/git-repository-browser-kiln.png[Kiln Repository Browser] Repository browser for git repositories hosted by link:http://www.fogbugz.com/version-control[Kiln]. Options include: @@ -525,7 +525,7 @@ URL:: [#visual-studio-team-services-repository-browser] ==== Microsoft Team Foundation Server/Visual Studio Team Services -image:/images/git-repository-browser-microsoft.png[Microsoft Repository Browser] +image:images/git-repository-browser-microsoft.png[Microsoft Repository Browser] Repository browser for git repositories hosted by link:https://azure.microsoft.com/en-us/solutions/devops/[Azure DevOps]. Options include: @@ -539,7 +539,7 @@ URL or name:: [bitbucketweb-repository-browser] ==== bitbucketweb -image:/images/git-repository-browser-bitbucket.png[Bitbucket Repository Browser] +image:images/git-repository-browser-bitbucket.png[Bitbucket Repository Browser] Repository browser for git repositories hosted by link:https://bitbucket.org/[Bitbucket]. Options include: @@ -553,7 +553,7 @@ URL:: [bitbucketserver-repository-browser] ==== bitbucketserver -image:/images/git-repository-browser-bitbucketserver.png[Bitbucket Server Repository Browser] +image:images/git-repository-browser-bitbucketserver.png[Bitbucket Server Repository Browser] Repository browser for git repositories hosted by an on-premises Bitbucket Server installation. Options include: @@ -567,7 +567,7 @@ URL:: [#cgit-repository-browser] ==== cgit -image:/images/git-repository-browser-cgit.png[CGit Repository Browser] +image:images/git-repository-browser-cgit.png[CGit Repository Browser] Repository browser for git repositories hosted by link:https://git.zx2c4.com/cgit/[cgit]. Options include: @@ -581,7 +581,7 @@ URL:: [#gitblit-repository-browser] ==== gitblit -image:/images/git-repository-browser-gitblit.png[GitBlit Repository Browser] +image:images/git-repository-browser-gitblit.png[GitBlit Repository Browser] [[gitblit-url]] GitBlit root url:: @@ -598,7 +598,7 @@ Project name in GitBlit:: [#githubweb-repository-browser] ==== githubweb -image:/images/git-repository-browser-github.png[GitHub Repository Browser] +image:images/git-repository-browser-github.png[GitHub Repository Browser] Repository browser for git repositories hosted by link:https://github.com//[GitHub]. Options include: @@ -612,7 +612,7 @@ URL:: [#gitiles-repository-browser] ==== gitiles -image:/images/git-repository-browser-gitiles.png[Gitiles Repository Browser] +image:images/git-repository-browser-gitiles.png[Gitiles Repository Browser] Repository browser for git repositories hosted by link:https://gerrit.googlesource.com/gitiles/[Gitiles]. Options include: @@ -627,7 +627,7 @@ gitiles root url:: [#gitlab-com-repository-browser] ==== gitlab -image:/images/git-repository-browser-gitlab.png[GitLab Repository Browser] +image:images/git-repository-browser-gitlab.png[GitLab Repository Browser] Repository browser for git repositories hosted by link:https://gitlab.com/[GitLab]. Options include: @@ -648,7 +648,7 @@ Version:: [#gitlist-repository-browser] ==== gitlist -image:/images/git-repository-browser-gitlist.png[Gitlist Repository Browser] +image:images/git-repository-browser-gitlist.png[Gitlist Repository Browser] Repository browser for git repositories hosted by link:https://gitlist.org/[GitList]. Options include: @@ -674,7 +674,7 @@ URL:: [#gitweb-repository-browser] ==== gitweb -image:/images/git-repository-browser-gitweb.png[Gitweb Repository Browser] +image:images/git-repository-browser-gitweb.png[Gitweb Repository Browser] Repository browser for git repositories hosted by link:https://git-scm.com/docs/gitweb[GitWeb]. Options include: @@ -688,7 +688,7 @@ URL:: [#gogs-repository-browser] ==== gogs -image:/images/git-repository-browser-gogs.png[Gogs Repository Browser] +image:images/git-repository-browser-gogs.png[Gogs Repository Browser] Repository browser for git repositories hosted by link:https://gogs.io/[Gogs]. Options include: @@ -720,7 +720,7 @@ Repository name in Phab:: [#redmineweb-repository-browser] ==== redmineweb -image:/images/git-repository-browser-redmine.png[Redmine Repository Browser] +image:images/git-repository-browser-redmine.png[Redmine Repository Browser] Repository browser for git repositories hosted by link:https://www.redmine.org/[Redmine]. Options include: @@ -734,7 +734,7 @@ URL:: [#rhodecode-repository-browser] ==== rhodecode -image:/images/git-repository-browser-rhodecode.png[RhodeCode Repository Browser] +image:images/git-repository-browser-rhodecode.png[RhodeCode Repository Browser] Repository browser for git repositories hosted by link:https://thodecode.com/[RhodeCode]. Options include: @@ -748,7 +748,7 @@ URL:: [#stash-repository-browser] ==== stash -image:/images/git-repository-browser-stash.png[Stash Repository Browser] +image:images/git-repository-browser-stash.png[Stash Repository Browser] Stash is now called *BitBucket Server*. Repository browser for git repositories hosted by link:https://www.atlassian.com/software/bitbucket[BitBucket Server]. @@ -763,7 +763,7 @@ URL:: [#viewgit-repository-browser] ==== viewgit -image:/images/git-repository-browser-viewgit.png[Viewgit Repository Browser] +image:images/git-repository-browser-viewgit.png[Viewgit Repository Browser] Repository browser for git repositories hosted by link:https://www.openhub.net/p/viewgit[viewgit]. Options include: @@ -824,7 +824,7 @@ The extensions can adjust the amount of history retrieved, how long the retrieva [#advanced-clone-behaviours] ==== Advanced clone behaviours -image:/images/git-advanced-clone-behaviours.png[Advanced clone behaviours] +image:images/git-advanced-clone-behaviours.png[Advanced clone behaviours] Advanced clone behaviors modify the `link:https://git-scm.com/docs/git-clone[git clone]` and `link:https://git-scm.com/docs/git-fetch[git fetch]` commands. They control: @@ -871,7 +871,7 @@ Fetch tags:: [#prune-stale-remote-tracking-branches] ==== Prune stale remote tracking branches -image:/images/git-prune-stale-remote-tracking-branches.png[Prune stale remote tracking branches] +image:images/git-prune-stale-remote-tracking-branches.png[Prune stale remote tracking branches] Removes remote tracking branches from the local workspace if they no longer exist on the remote. See `link:https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-empruneem[git remote prune]` and `link:https://git-scm.com/docs/git-fetch#_pruning[git fetch --prune]` for more details. @@ -879,7 +879,7 @@ See `link:https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-empru [#prune-stale-tags] ==== Prune stale tags -image:/images/git-prune-stale-tags.png[Prune stale tags] +image:images/git-prune-stale-tags.png[Prune stale tags] Removes tags from the local workspace before fetch if they no longer exist on the remote. If stale tags are not pruned, deletion of a remote tag will not remove the local tag in the workspace. @@ -895,7 +895,7 @@ The extensions can adjust the maximum duration of the checkout operation, the us [#advanced-checkout-behaviors] ==== Advanced checkout behaviors -image:/images/git-advanced-checkout-behaviors.png[Advanced checkout behaviors] +image:images/git-advanced-checkout-behaviors.png[Advanced checkout behaviors] Advanced checkout behaviors modify the `link:https://git-scm.com/docs/git-checkout[git checkout]` command. Advanced checkout behaviors include @@ -909,7 +909,7 @@ Timeout (in minutes) for checkout operation:: [#advanced-sub-modules-behaviours] ==== Advanced sub-modules behaviours -image:/images/git-advanced-sub-modules-behaviours.png[Advanced sub-modules behaviours] +image:images/git-advanced-sub-modules-behaviours.png[Advanced sub-modules behaviours] Advanced sub-modules behaviors modify the `link:https://git-scm.com/docs/git-submodule[git submodule]` commands. They control: @@ -974,7 +974,7 @@ Shallow clone depth:: [#checkout-to-a-sub-directory] ==== Checkout to a sub-directory -image:/images/git-checkout-to-a-sub-directory.png[Checkout to a sub-directory] +image:images/git-checkout-to-a-sub-directory.png[Checkout to a sub-directory] Checkout to a subdirectory of the workspace instead of using the workspace root. @@ -990,7 +990,7 @@ Local subdirectory for repo:: [#checkout-to-specific-local-branch] ==== Checkout to specific local branch -image:/images/git-checkout-to-specific-local-branch.png[Checkout to specific local branch] +image:images/git-checkout-to-specific-local-branch.png[Checkout to specific local branch] Branch name:: @@ -1002,7 +1002,7 @@ Branch name:: [#wipe-out-repository-and-force-clone] ==== Wipe out repository and force clone -image:/images/git-wipe-out-repository-and-force-clone.png[Wipe out repository and force clone] +image:images/git-wipe-out-repository-and-force-clone.png[Wipe out repository and force clone] Delete the contents of the workspace before build and before checkout. Deletes the git repository inside the workspace and will force a full clone. @@ -1010,7 +1010,7 @@ Deletes the git repository inside the workspace and will force a full clone. [clean-after-checkout] ==== Clean after checkout -image:/images/git-clean-after-checkout.png[Clean after checkout] +image:images/git-clean-after-checkout.png[Clean after checkout] Clean the workspace *after* every checkout by deleting all untracked files and directories, including those which are specified in `.gitignore`. Resets all tracked files to their versioned state. @@ -1028,7 +1028,7 @@ Delete untracked nested repositories:: [#clean-before-checkout] ==== Clean before checkout -image:/images/git-clean-before-checkout.png[Clean before checkout] +image:images/git-clean-before-checkout.png[Clean before checkout] Clean the workspace *before* every checkout by deleting all untracked files and directories, including those which are specified in .gitignore. Resets all tracked files to their versioned state. @@ -1046,7 +1046,7 @@ Delete untracked nested repositories:: [#sparse-checkout-paths] ==== Sparse checkout paths -image:/images/git-sparse-checkout-paths.png[Sparse checkout paths] +image:images/git-sparse-checkout-paths.png[Sparse checkout paths] Specify the paths that you'd like to sparse checkout. This may be used for saving space (Think about a reference repository). @@ -1061,7 +1061,7 @@ Path:: [#git-lfs-pull-after-checkout] ==== Git LFS pull after checkout -image:/images/git-lfs-pull-after-checkout.png[Git LFS pull after checkout] +image:images/git-lfs-pull-after-checkout.png[Git LFS pull after checkout] Enable https://git-lfs.github.com/[git large file support] for the workspace by pulling large files after the checkout completes. Requires that the controller and each agent performing an LFS checkout have installed `git lfs`. @@ -1075,7 +1075,7 @@ Changelog extensions adapt the changelog calculations for different cases. [#calculate-changelog-against-a-specific-branch] ==== Calculate changelog against a specific branch -image:/images/git-calculate-changelog-against-a-specific-branch.png[Calculate changelog against a specific branch] +image:images/git-calculate-changelog-against-a-specific-branch.png[Calculate changelog against a specific branch] 'Calculate changelog against a specific branch' uses the specified branch to compute the changelog instead of computing it based on the previous build. This extension can be useful for computing changes related to a known base branch, especially in environments which do not have the concept of a "pull request". @@ -1091,7 +1091,7 @@ Name of branch:: [#use-commit-author-in-changelog] ==== Use commit author in changelog -image:/images/git-use-commit-author-in-changelog.png[Use commit author in changelog] +image:images/git-use-commit-author-in-changelog.png[Use commit author in changelog] The default behavior is to use the Git commit's "Committer" value in build changesets. If this option is selected, the git commit's "Author" value is used instead. @@ -1104,7 +1104,7 @@ Tagging extensions allow the plugin to apply tags in the current workspace. [#create-a-tag-for-every-build] ==== Create a tag for every build -image:/images/git-create-a-tag-for-every-build.png[Create a tag for every build] +image:images/git-create-a-tag-for-every-build.png[Create a tag for every build] Create a tag in the workspace for every build to unambiguously mark the commit that was built. You can combine this with Git publisher to push the tags to the remote repository. @@ -1119,14 +1119,14 @@ They can ignore notifications of a change or force a deeper evaluation of the co [#dont-trigger-a-build-on-commit-notifications] ==== Don't trigger a build on commit notifications -image:/images/git-do-not-trigger-a-build-on-commit-notifications.png[Do not trigger a build on commit notifications] +image:images/git-do-not-trigger-a-build-on-commit-notifications.png[Do not trigger a build on commit notifications] If checked, this repository will be ignored when the notifyCommit URL is accessed whether the repository matches or not. [#force-polling-using-workspace] ==== Force polling using workspace -image:/images/git-force-polling-using-workspace.png[Force polling using workspace] +image:images/git-force-polling-using-workspace.png[Force polling using workspace] The git plugin polls remotely using `ls-remote` when configured with a single branch (no wildcards!). When this extension is enabled, the polling is performed from a cloned copy of the workspace instead of using `ls-remote`. @@ -1140,7 +1140,7 @@ In addition, the administrator may need to < Date: Mon, 5 Aug 2024 12:12:51 +1000 Subject: [PATCH 2/4] [JENKINS-73568] rewrite the tests using RealJenkinsRule so test doesn't need to be skipped depending on Jenkins core version" (#1625) * Use RealJenkinsRule Signed-off-by: Olivier Lamy * Rewrite tests using RealJenkinsRule Signed-off-by: Olivier Lamy * exclusion not needed Signed-off-by: Olivier Lamy * add comments about the exclusion Signed-off-by: Olivier Lamy --------- Signed-off-by: Olivier Lamy --- pom.xml | 8 + .../plugins/git/FIPSModeUrlCheckTest.java | 410 +++++++++--------- .../plugins/git/FIPSModeSCMSourceTest.java | 84 ++-- 3 files changed, 239 insertions(+), 263 deletions(-) diff --git a/pom.xml b/pom.xml index a5365cf294..2eddb9dc94 100644 --- a/pom.xml +++ b/pom.xml @@ -229,6 +229,14 @@ git-tag-message 1.7.1 test + + + + ${project.groupId} + ${project.artifactId} + + org.testcontainers diff --git a/src/test/java/hudson/plugins/git/FIPSModeUrlCheckTest.java b/src/test/java/hudson/plugins/git/FIPSModeUrlCheckTest.java index 9ef1eb01df..2f59c84c59 100644 --- a/src/test/java/hudson/plugins/git/FIPSModeUrlCheckTest.java +++ b/src/test/java/hudson/plugins/git/FIPSModeUrlCheckTest.java @@ -16,13 +16,11 @@ import hudson.model.FreeStyleProject; import hudson.model.Result; import hudson.util.FormValidation; -import hudson.util.VersionNumber; import java.io.File; import java.nio.file.Files; import java.util.List; import jenkins.branch.MultiBranchProject; import jenkins.plugins.git.GitSCMSource; -import jenkins.security.FIPS140; import org.apache.commons.lang.StringUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.StoredConfig; @@ -32,170 +30,161 @@ import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; import org.jetbrains.annotations.NotNull; import org.junit.Assume; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.FlagRule; -import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.RealJenkinsRule; import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.BindMode; public class FIPSModeUrlCheckTest { - @ClassRule - public static final FlagRule FIPS_FLAG = - FlagRule.systemProperty(FIPS140.class.getName() + ".COMPLIANCE", "true"); - - @Rule - public JenkinsRule r = new JenkinsRule(); + @Rule public RealJenkinsRule rule = new RealJenkinsRule().omitPlugins("eddsa-api", "trilead-api", "git-tag-message") + .javaOptions("-Djenkins.security.FIPS140.COMPLIANCE=true"); @Rule public TemporaryFolder directory = new TemporaryFolder(); - @BeforeClass - public static void checkJenkinsVersion() { - /* TODO: Remove when failing tests are fixed */ - /* JenkinsRule throws an exception before any test method is executed */ - /* Guess the version number from the Maven command line property */ - /* Default version number copied from pom.xml jenkins.version */ - VersionNumber jenkinsFailsTests = new VersionNumber("2.461"); - VersionNumber jenkinsVersion = new VersionNumber(System.getProperty("jenkins.version", "2.440.3")); - /** Skip tests to avoid delaying plugin BOM and Spring Security 6.x Upgrade */ - boolean skipTests = false; - if (jenkinsVersion.isNewerThanOrEqualTo(jenkinsFailsTests)) { - skipTests = true; - } - Assume.assumeFalse(skipTests); - } @Test - public void testFIPSLtsMethod() { - assertThat(GitSCMSource.isFIPSCompliantTLS(null, "http://github.com/cheese/wine"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "http://github.com/cheese/wine"), is(false)); - assertThat(GitSCMSource.isFIPSCompliantTLS(null, "https://github.com/cheese/wine"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "https://github.com/cheese/wine"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS(null, "git@github.com:cheese/wine.git"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "git@github.com:cheese/wine.git"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS(null, "git://github.com/cheese/wine"), is(true)); - assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "git://github.com/cheese/wine"), is(false)); + public void testFIPSLtsMethod() throws Throwable { + rule.then( r -> { + assertThat(GitSCMSource.isFIPSCompliantTLS(null, "http://github.com/cheese/wine"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "http://github.com/cheese/wine"), is(false)); + assertThat(GitSCMSource.isFIPSCompliantTLS(null, "https://github.com/cheese/wine"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "https://github.com/cheese/wine"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS(null, "git@github.com:cheese/wine.git"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "git@github.com:cheese/wine.git"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS(null, "git://github.com/cheese/wine"), is(true)); + assertThat(GitSCMSource.isFIPSCompliantTLS("beer", "git://github.com/cheese/wine"), is(false)); + }); } @Test public void testGitSCMSourceCheck() throws Throwable { - SystemCredentialsProvider.getInstance() - .getCredentials() - .add(new UsernamePasswordCredentialsImpl( - CredentialsScope.GLOBAL, "mycreds", null, "jenkins", "s3cr3t")); - SystemCredentialsProvider.getInstance().save(); - MultiBranchProject mbp = r.createProject(WorkflowMultiBranchProject.class, "mbp"); - GitSCMSource.DescriptorImpl descriptor = ExtensionList.lookupSingleton(GitSCMSource.DescriptorImpl.class); + rule.then( r -> { + SystemCredentialsProvider.getInstance() + .getCredentials() + .add(new UsernamePasswordCredentialsImpl( + CredentialsScope.GLOBAL, "mycreds", null, "jenkins", "s3cr3t")); + SystemCredentialsProvider.getInstance().save(); + MultiBranchProject mbp = r.createProject(WorkflowMultiBranchProject.class, "mbp"); + GitSCMSource.DescriptorImpl descriptor = ExtensionList.lookupSingleton(GitSCMSource.DescriptorImpl.class); - { - // http with creds rejected - FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "http://github.com/foo/beer"); - assertThat(validation.kind, is(FormValidation.Kind.ERROR)); - assertThat(validation.getMessage(), containsString(Messages.git_fips_url_notsecured())); - } + { + // http with creds rejected + FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "http://github.com/foo/beer"); + assertThat(validation.kind, is(FormValidation.Kind.ERROR)); + assertThat(validation.getMessage(), containsString(Messages.git_fips_url_notsecured())); + } - { - // https with creds ok - FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "https://github.com/foo/vegemite"); - assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + { + // https with creds ok + FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "https://github.com/foo/vegemite"); + assertThat(validation.kind, is(FormValidation.Kind.OK)); + } - { - // ssh with creds ok - FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "git@github.com:foo/wine.git"); - assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + { + // ssh with creds ok + FormValidation validation = descriptor.doCheckRemote(mbp, "mycreds", "git@github.com:foo/wine.git"); + assertThat(validation.kind, is(FormValidation.Kind.OK)); + } - { - // http without creds ok - FormValidation validation = descriptor.doCheckRemote(mbp, null, "http://github.com/foo/cheese"); - assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + { + // http without creds ok + FormValidation validation = descriptor.doCheckRemote(mbp, null, "http://github.com/foo/cheese"); + assertThat(validation.kind, is(FormValidation.Kind.OK)); + } + }); } @Test public void testUserRemoteConfigCheck() throws Throwable { - SystemCredentialsProvider.getInstance() - .getCredentials() - .add(new UsernamePasswordCredentialsImpl( - CredentialsScope.GLOBAL, "mycreds", null, "jenkins", "s3cr3t")); - SystemCredentialsProvider.getInstance().save(); - FreeStyleProject p = r.createProject(FreeStyleProject.class, "mbp"); - UserRemoteConfig.DescriptorImpl descriptor = - ExtensionList.lookupSingleton(UserRemoteConfig.DescriptorImpl.class); + Assume.assumeTrue(DockerClientFactory.instance().isDockerAvailable()); + // ssh with credentials all good + try (GitServerContainer containerUnderTest = + new GitServerContainer(GitServerVersions.V2_45.getDockerImageName()).withGitRepo("someRepo")) { + containerUnderTest.withClasspathResourceMapping( + "ssh-keys/id_rsa.pub", "/home/git/.ssh/authorized_keys", BindMode.READ_ONLY); + containerUnderTest.withClasspathResourceMapping( + "sshd_config", "/etc/ssh/sshd_config", BindMode.READ_ONLY); - { - // http with credentials rejected - FormValidation validation = descriptor.doCheckUrl(p, "mycreds", "http://github.com/olamy/beer"); - assertThat(validation.kind, is(FormValidation.Kind.ERROR)); - assertThat(validation.getMessage(), containsString(Messages.git_fips_url_notsecured())); - } + containerUnderTest.start(); - { - // https without credentials all good - FormValidation validation = descriptor.doCheckUrl(p, null, "https://github.com/jenkinsci/git-plugin"); - assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + SshIdentity sshClientIdentity = new SshIdentity( + this.getClass() + .getClassLoader() + .getResourceAsStream("ssh-keys/id_rsa") + .readAllBytes(), + this.getClass() + .getClassLoader() + .getResourceAsStream("ssh-keys/id_rsa.pub") + .readAllBytes(), + new byte[0]); + byte[] privateKey = sshClientIdentity.getPrivateKey(); + byte[] passphrase = sshClientIdentity.getPassphrase(); + // ssh://git@localhost:33011/srv/git/someRepo.git + // we don't want the user part of the uri or jgit will use this user + // and we want to be sure to test our implementation with dynamic user + final String repoUrl = StringUtils.remove(containerUnderTest.getGitRepoURIAsSSH().toString(), "git@"); + rule.then( r -> { + BasicSSHUserPrivateKey sshUserPrivateKey = getBasicSSHUserPrivateKey(privateKey, passphrase); + SystemCredentialsProvider.getInstance().getCredentials().add(sshUserPrivateKey); + SystemCredentialsProvider.getInstance() + .getCredentials() + .add(new UsernamePasswordCredentialsImpl( + CredentialsScope.GLOBAL, "mycreds", null, "jenkins", "s3cr3t")); + SystemCredentialsProvider.getInstance().save(); + FreeStyleProject p = r.createProject(FreeStyleProject.class, "mbp"); + UserRemoteConfig.DescriptorImpl descriptor = + ExtensionList.lookupSingleton(UserRemoteConfig.DescriptorImpl.class); - Assume.assumeTrue(DockerClientFactory.instance().isDockerAvailable()); + { + // http with credentials rejected + FormValidation validation = descriptor.doCheckUrl(p, "mycreds", "http://github.com/olamy/beer"); + assertThat(validation.kind, is(FormValidation.Kind.ERROR)); + assertThat(validation.getMessage(), containsString(Messages.git_fips_url_notsecured())); + } - { - // ssh with credentials all good - try (GitServerContainer containerUnderTest = - new GitServerContainer(GitServerVersions.V2_45.getDockerImageName()).withGitRepo("someRepo")) { - containerUnderTest.withClasspathResourceMapping( - "ssh-keys/id_rsa.pub", "/home/git/.ssh/authorized_keys", BindMode.READ_ONLY); - containerUnderTest.withClasspathResourceMapping( - "sshd_config", "/etc/ssh/sshd_config", BindMode.READ_ONLY); + { + // https without credentials all good + FormValidation validation = descriptor.doCheckUrl(p, null, "https://github.com/jenkinsci/git-plugin"); + assertThat(validation.kind, is(FormValidation.Kind.OK)); + } - containerUnderTest.start(); + Assume.assumeTrue(DockerClientFactory.instance().isDockerAvailable()); - SshIdentity sshClientIdentity = new SshIdentity( - this.getClass() - .getClassLoader() - .getResourceAsStream("ssh-keys/id_rsa") - .readAllBytes(), - this.getClass() - .getClassLoader() - .getResourceAsStream("ssh-keys/id_rsa.pub") - .readAllBytes(), - new byte[0]); - BasicSSHUserPrivateKey sshUserPrivateKey = getBasicSSHUserPrivateKey(sshClientIdentity); - SystemCredentialsProvider.getInstance().getCredentials().add(sshUserPrivateKey); - String repoUrl = containerUnderTest.getGitRepoURIAsSSH().toString(); - // ssh://git@localhost:33011/srv/git/someRepo.git - // we don't want the user part of the uri or jgit will use this user - // and we want to be sure to test our implementation with dynamic user - repoUrl = StringUtils.remove(repoUrl, "git@"); - FormValidation validation = descriptor.doCheckUrl(p, sshUserPrivateKey.getId(), repoUrl); - assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + { + FormValidation validation = descriptor.doCheckUrl(p, sshUserPrivateKey.getId(), repoUrl); + assertThat(validation.kind, is(FormValidation.Kind.OK)); + } + }); } - { - // http without credentials all good - try (GitHttpServerContainer containerUnderTest = - new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { - containerUnderTest.start(); + // http without credentials all good + try (GitHttpServerContainer containerUnderTest = + new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { + containerUnderTest.start(); + String repoUri = containerUnderTest.getGitRepoURIAsHttp().toString(); + rule.then( r -> { + FreeStyleProject p = r.createProject(FreeStyleProject.class, "mbp2"); + UserRemoteConfig.DescriptorImpl descriptor = + ExtensionList.lookupSingleton(UserRemoteConfig.DescriptorImpl.class); // no TLS is fine without credentials FormValidation validation = descriptor.doCheckUrl( - p, null, containerUnderTest.getGitRepoURIAsHttp().toString()); + p, null, repoUri); assertThat(validation.kind, is(FormValidation.Kind.OK)); - } + }); } + } - private static BasicSSHUserPrivateKey getBasicSSHUserPrivateKey(SshIdentity sshIdentity) { + private static BasicSSHUserPrivateKey getBasicSSHUserPrivateKey(byte[] privateKey, byte[] passphrase) { BasicSSHUserPrivateKey.PrivateKeySource privateKeySource = new BasicSSHUserPrivateKey.PrivateKeySource() { @NotNull @Override public List getPrivateKeys() { - return List.of(new String(sshIdentity.getPrivateKey())); + return List.of(new String(privateKey)); } }; return new BasicSSHUserPrivateKey( @@ -203,108 +192,111 @@ public List getPrivateKeys() { "some-id", "git", privateKeySource, - new String(sshIdentity.getPassphrase()), + new String(passphrase), "description"); } @Test public void gitStepTLSCheck() throws Throwable { - WorkflowJob p = r.createProject(WorkflowJob.class, "some project"); - { - // http with creds rejected - p.setDefinition(new CpsFlowDefinition( - "node {\n" + - " dir('foo') {\n" + - " git url: 'http://foo.com/beer.git', credentialsId: 'yup'\n" + - " }\n" + - "}", true)); - WorkflowRun b = r.buildAndAssertStatus(Result.FAILURE, p); - r.assertLogContains(Messages.git_fips_url_notsecured(), b); - } - Assume.assumeTrue(DockerClientFactory.instance().isDockerAvailable()); + try (GitHttpServerContainer containerUnderTest = + new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { + containerUnderTest.start(); + // need to have at least on revision to avoid build failure + File tmp = directory.newFolder(); + Git git = Git.cloneRepository() + .setURI(containerUnderTest.getGitRepoURIAsHttp().toString()) + .setDirectory(tmp) + .call(); + StoredConfig storedConfig = git.getRepository().getConfig(); + storedConfig.setBoolean("commit", null, "gpgsign", false); + storedConfig.setBoolean("tag", null, "gpgSign", false); + storedConfig.save(); + Files.writeString(new File(tmp, "foo.txt").toPath(), "nothing too see here"); + git.add().addFilepattern("foo.txt").call(); + git.commit().setMessage("add foo").call(); + git.push().call(); + String repoUri = containerUnderTest.getGitRepoURIAsHttp().toString(); + rule.then(r -> { + WorkflowJob p = r.createProject(WorkflowJob.class, "some project"); + { + // http with creds rejected + p.setDefinition(new CpsFlowDefinition( + "node {\n" + + " dir('foo') {\n" + + " git url: 'http://foo.com/beer.git', credentialsId: 'yup'\n" + + " }\n" + + "}", true)); + WorkflowRun b = r.buildAndAssertStatus(Result.FAILURE, p); + r.assertLogContains(Messages.git_fips_url_notsecured(), b); + } - { - // http without creds not rejected - try (GitHttpServerContainer containerUnderTest = - new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { - containerUnderTest.start(); - // need to have at least on revision to avoid build failure - File tmp = directory.newFolder(); - Git git = Git.cloneRepository() - .setURI(containerUnderTest.getGitRepoURIAsHttp().toString()) - .setDirectory(tmp) - .call(); - StoredConfig storedConfig = git.getRepository().getConfig(); - storedConfig.setBoolean("commit", null, "gpgsign", false); - storedConfig.setBoolean("tag", null, "gpgSign", false); - storedConfig.save(); - Files.writeString(new File(tmp, "foo.txt").toPath(), "nothing too see here"); - git.add().addFilepattern("foo.txt").call(); - git.commit().setMessage("add foo").call(); - git.push().call(); - - p.setDefinition(new CpsFlowDefinition( - "node {\n" + - " dir('foo') {\n" + - " git url: '" + containerUnderTest.getGitRepoURIAsHttp() + "', changelog: false\n" + - " }\n" + - "}", true)); - WorkflowRun b = r.buildAndAssertStatus(Result.SUCCESS, p); - } + { + // http without creds not rejected + p.setDefinition(new CpsFlowDefinition( + "node {\n" + + " dir('foo') {\n" + + " git url: '" + repoUri + "', changelog: false\n" + + " }\n" + + "}", true)); + r.buildAndAssertStatus(Result.SUCCESS, p); + } + }); } } @Test public void checkoutStepTLSCheck() throws Throwable { - WorkflowJob p = r.createProject(WorkflowJob.class, "some project"); - { - // http with creds rejected - // Intentionally using modern syntax to check compatibility - p.setDefinition(new CpsFlowDefinition( - "node {\n" + - " dir('foo') {\n" + - " checkout scmGit(branches: [[name: 'master']],\n" + - " userRemoteConfigs: [[credentialsId: 'foocreds', url: 'http://github.com/foo/beer.git']])\n" + - " }\n" + - "}", true)); - WorkflowRun b = r.buildAndAssertStatus(Result.FAILURE, p); - r.assertLogContains(Messages.git_fips_url_notsecured(), b); - } - Assume.assumeTrue(DockerClientFactory.instance().isDockerAvailable()); + try (GitHttpServerContainer containerUnderTest = + new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { + containerUnderTest.start(); + // need to have at least on revision to avoid build failure + File tmp = directory.newFolder(); + Git git = Git.cloneRepository() + .setURI(containerUnderTest.getGitRepoURIAsHttp().toString()) + .setDirectory(tmp) + .call(); + StoredConfig storedConfig = git.getRepository().getConfig(); + storedConfig.setBoolean("commit", null, "gpgsign", false); + storedConfig.setBoolean("tag", null, "gpgSign", false); + storedConfig.save(); + Files.writeString(new File(tmp, "foo.txt").toPath(), "nothing too see here"); + git.add().addFilepattern("foo.txt").call(); + git.commit().setMessage("add foo").call(); + git.push().call(); + String repoUri = containerUnderTest.getGitRepoURIAsHttp().toString(); + rule.then(r -> { + WorkflowJob p = r.createProject(WorkflowJob.class, "some project"); + { + // http with creds rejected + // Intentionally using modern syntax to check compatibility + p.setDefinition(new CpsFlowDefinition( + "node {\n" + + " dir('foo') {\n" + + " checkout scmGit(branches: [[name: 'master']],\n" + + " userRemoteConfigs: [[credentialsId: 'foocreds', url: 'http://github.com/foo/beer.git']])\n" + + " }\n" + + "}", true)); + WorkflowRun b = r.buildAndAssertStatus(Result.FAILURE, p); + r.assertLogContains(Messages.git_fips_url_notsecured(), b); + } - { - // http without creds not rejected - try (GitHttpServerContainer containerUnderTest = - new GitHttpServerContainer(GitServerVersions.V2_45.getDockerImageName())) { - containerUnderTest.start(); - // need to have at least on revision to avoid build failure - File tmp = directory.newFolder(); - Git git = Git.cloneRepository() - .setURI(containerUnderTest.getGitRepoURIAsHttp().toString()) - .setDirectory(tmp) - .call(); - StoredConfig storedConfig = git.getRepository().getConfig(); - storedConfig.setBoolean("commit", null, "gpgsign", false); - storedConfig.setBoolean("tag", null, "gpgSign", false); - storedConfig.save(); - Files.writeString(new File(tmp, "foo.txt").toPath(), "nothing too see here"); - git.add().addFilepattern("foo.txt").call(); - git.commit().setMessage("add foo").call(); - git.push().call(); + { + // http without creds not rejected + // Intentionally using old syntax to check compatibility + p.setDefinition(new CpsFlowDefinition( + "node {\n" + + " dir('foo') {\n" + + " checkout([$class: 'GitSCM',\n" + + " branches: [[name: '*/master']],\n" + + " userRemoteConfigs: [[url: '" + repoUri + "']]])\n" + + " }\n" + + "}", true)); + r.buildAndAssertStatus(Result.SUCCESS, p); + } - // Intentionally using old syntax to check compatibility - p.setDefinition(new CpsFlowDefinition( - "node {\n" + - " dir('foo') {\n" + - " checkout([$class: 'GitSCM',\n" + - " branches: [[name: '*/master']],\n" + - " userRemoteConfigs: [[url: '" + containerUnderTest.getGitRepoURIAsHttp() + "']]])\n" + - " }\n" + - "}", true)); - WorkflowRun b = r.buildAndAssertStatus(Result.SUCCESS, p); - } + }); } } } diff --git a/src/test/java/jenkins/plugins/git/FIPSModeSCMSourceTest.java b/src/test/java/jenkins/plugins/git/FIPSModeSCMSourceTest.java index 641c6f06c2..2d8b38f348 100644 --- a/src/test/java/jenkins/plugins/git/FIPSModeSCMSourceTest.java +++ b/src/test/java/jenkins/plugins/git/FIPSModeSCMSourceTest.java @@ -1,20 +1,14 @@ package jenkins.plugins.git; +import hudson.logging.LogRecorder; import hudson.model.TaskListener; import hudson.plugins.git.GitException; import hudson.util.StreamTaskListener; -import hudson.util.VersionNumber; -import jenkins.security.FIPS140; -import org.junit.Assume; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.jvnet.hudson.test.FlagRule; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.RealJenkinsRule; -import java.io.IOException; +import java.util.List; import java.util.logging.Level; import static org.hamcrest.CoreMatchers.containsString; @@ -25,53 +19,35 @@ public class FIPSModeSCMSourceTest { - @ClassRule - public static final FlagRule FIPS_FLAG = - FlagRule.systemProperty(FIPS140.class.getName() + ".COMPLIANCE", "true"); - - @Rule - public JenkinsRule rule = new JenkinsRule(); - - @Rule - public LoggerRule logger = new LoggerRule(); - - @BeforeClass - public static void checkJenkinsVersion() { - /* TODO: Remove when failing tests are fixed */ - /* JenkinsRule throws an exception before any test method is executed */ - /* Guess the version number from the Maven command line property */ - /* Default version number copied from pom.xml jenkins.version */ - VersionNumber jenkinsFailsTests = new VersionNumber("2.461"); - VersionNumber jenkinsVersion = new VersionNumber(System.getProperty("jenkins.version", "2.440.3")); - /** Skip tests to avoid delaying plugin BOM and Spring Security 6.x Upgrade */ - boolean skipTests = false; - if (jenkinsVersion.isNewerThanOrEqualTo(jenkinsFailsTests)) { - skipTests = true; - } - Assume.assumeFalse(skipTests); - } + @Rule public RealJenkinsRule rule = new RealJenkinsRule().omitPlugins("eddsa-api", "trilead-api", "git-tag-message") + .javaOptions("-Djenkins.security.FIPS140.COMPLIANCE=true") + .withLogger(AbstractGitSCMSource.class, Level.SEVERE); @Test @SuppressWarnings("deprecation") - public void remotesAreNotFetchedTest() throws IOException, InterruptedException { - GitSCMSource source = new GitSCMSource("http://insecure-repo"); - // Credentials are null, so we should have no FIPS error - logger.record(AbstractGitSCMSource.class, Level.SEVERE); - logger.capture(10); - TaskListener listener = StreamTaskListener.fromStderr(); - assertThrows("expected exception as repo doesn't exist", GitException.class, () ->source.fetch(listener)); - assertThat("We should no see the error in the logs", logger.getMessages().size(), is(0)); - - // Using creds we should be getting an exception - Throwable exception = assertThrows("We're not saving creds", IllegalArgumentException.class, () -> source.setCredentialsId("cred-id")); - assertThat(exception.getMessage(), containsString("FIPS requires a secure channel")); - assertThat("credentials are not saved", source.getCredentialsId(), nullValue()); - - // Using old constructor (restricted since 3.4.0) to simulate credentials are being set with unsecure connection - // This would be equivalent to a user manually adding credentials to config.xml - GitSCMSource anotherSource = new GitSCMSource("fake", "http://insecure", "credentialsId", "", "", true); - exception = assertThrows("fetch was interrupted so no credential was leaked", IllegalArgumentException.class, () -> anotherSource.fetch(listener)); - assertThat("We should have a severe log indicating the error", logger.getMessages().size(), is(1)); - assertThat("Exception indicates problem", exception.getMessage(), containsString("FIPS requires a secure channel")); + public void remotesAreNotFetchedTest() throws Throwable { + rule.then( r -> { + GitSCMSource source = new GitSCMSource("http://insecure-repo"); + TaskListener listener = StreamTaskListener.fromStderr(); + assertThrows("expected exception as repo doesn't exist", GitException.class, () -> source.fetch(listener)); + + LogRecorder logRecorder = new LogRecorder(AbstractGitSCMSource.class.getName()); + LogRecorder.Target target = new LogRecorder.Target(AbstractGitSCMSource.class.getName(), Level.SEVERE); + logRecorder.setLoggers(List.of(target)); + r.jenkins.getLog().getRecorders().add(logRecorder); + assertThat("We should no see the error in the logs", logRecorder.getLogRecords().size(), is(0)); + + // Using creds we should be getting an exception + Throwable exception = assertThrows("We're not saving creds", IllegalArgumentException.class, () -> source.setCredentialsId("cred-id")); + assertThat(exception.getMessage(), containsString("FIPS requires a secure channel")); + assertThat("credentials are not saved", source.getCredentialsId(), nullValue()); + + // Using old constructor (restricted since 3.4.0) to simulate credentials are being set with unsecure connection + // This would be equivalent to a user manually adding credentials to config.xml + GitSCMSource anotherSource = new GitSCMSource("fake", "http://insecure", "credentialsId", "", "", true); + exception = assertThrows("fetch was interrupted so no credential was leaked", IllegalArgumentException.class, () -> anotherSource.fetch(listener)); + assertThat("We should have a severe log indicating the error", logRecorder.getLogRecords().size(), is(1)); + assertThat("Exception indicates problem", exception.getMessage(), containsString("FIPS requires a secure channel")); + }); } } From 29a5456289b2d8ae73726839075b9283094c1265 Mon Sep 17 00:00:00 2001 From: Mark Waite Date: Sun, 4 Aug 2024 20:16:34 -0600 Subject: [PATCH 3/4] Restore compatibility for GitSampleRepoRule (#1626) * Restore compatibility for GitSampleRepoRule I forgot that there are other consumers of the Git plugin test suite. Plugin BOM automated tests detected the problem. * Remove code repetition introduced by prior commit --- src/test/java/hudson/plugins/git/GitStepTest.java | 8 ++++---- .../jenkins/plugins/git/GitSampleRepoRule.java | 15 ++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/test/java/hudson/plugins/git/GitStepTest.java b/src/test/java/hudson/plugins/git/GitStepTest.java index a5322cdfde..8eef466b23 100644 --- a/src/test/java/hudson/plugins/git/GitStepTest.java +++ b/src/test/java/hudson/plugins/git/GitStepTest.java @@ -328,7 +328,7 @@ private WorkflowJob createJob() throws Exception { public void testDoNotifyCommitWithInvalidApiToken() throws Exception { assumeTrue("Test class max time " + MAX_SECONDS_FOR_THESE_TESTS + " exceeded", isTimeAvailable()); createJob(); - String response = sampleRepo.notifyCommit(r, GitSampleRepoRule.INVALID_NOTIFY_COMMIT_TOKEN); + String response = sampleRepo.notifyCommitWithResults(r, GitSampleRepoRule.INVALID_NOTIFY_COMMIT_TOKEN); assertThat(response, containsString("Invalid access token")); } @@ -337,7 +337,7 @@ public void testDoNotifyCommitWithInvalidApiToken() throws Exception { public void testDoNotifyCommitWithAllowModeRandomValue() throws Exception { assumeTrue("Test class max time " + MAX_SECONDS_FOR_THESE_TESTS + " exceeded", isTimeAvailable()); createJob(); - String response = sampleRepo.notifyCommit(r, null); + String response = sampleRepo.notifyCommitWithResults(r, null); assertThat(response, containsString("An access token is required. Please refer to Git plugin documentation (https://plugins.jenkins.io/git/#plugin-content-push-notification-from-repository) for details.")); } @@ -349,7 +349,7 @@ public void testDoNotifyCommitWithSha1AndAllowModePollWithInvalidToken() throws createJob(); /* sha1 is ignored because invalid access token is provided */ String sha1 = "4b714b66959463a98e9dfb1983db5a39a39fa6d6"; - String response = sampleRepo.notifyCommit(r, GitSampleRepoRule.INVALID_NOTIFY_COMMIT_TOKEN, sha1); + String response = sampleRepo.notifyCommitWithResults(r, GitSampleRepoRule.INVALID_NOTIFY_COMMIT_TOKEN, sha1); assertThat(response, containsString("Invalid access token")); } @@ -361,7 +361,7 @@ public void testDoNotifyCommitWithSha1AndAllowModePoll() throws Exception { createJob(); /* sha1 is ignored because no access token is provided */ String sha1 = "4b714b66959463a98e9dfb1983db5a39a39fa6d6"; - String response = sampleRepo.notifyCommit(r, null, sha1); + String response = sampleRepo.notifyCommitWithResults(r, null, sha1); assertThat(response, containsString("An access token is required when using the sha1 parameter")); } diff --git a/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java b/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java index 152169719c..504035f59d 100644 --- a/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java +++ b/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java @@ -101,13 +101,18 @@ public final boolean mkdirs(String rel) throws IOException { return new File(this.sampleRepo, rel).mkdirs(); } - public String notifyCommit(JenkinsRule r) throws Exception { + public void notifyCommit(JenkinsRule r) throws Exception { String notifyCommitToken = ApiTokenPropertyConfiguration.get().generateApiToken("notifyCommit").getString("value"); - return notifyCommit(r, notifyCommitToken, null); + notifyCommitWithResults(r, notifyCommitToken, null); } - public String notifyCommit(JenkinsRule r, @CheckForNull String notifyCommitToken) throws Exception { - return notifyCommit(r, notifyCommitToken, null); + public String notifyCommitWithResults(JenkinsRule r) throws Exception { + String notifyCommitToken = ApiTokenPropertyConfiguration.get().generateApiToken("notifyCommit").getString("value"); + return notifyCommitWithResults(r, notifyCommitToken, null); + } + + public String notifyCommitWithResults(JenkinsRule r, @CheckForNull String notifyCommitToken) throws Exception { + return notifyCommitWithResults(r, notifyCommitToken, null); } /** @@ -126,7 +131,7 @@ public String notifyCommit(JenkinsRule r, @CheckForNull String notifyCommitToken * @param notifyCommitToken token used for notifyCommit authentication * @param sha1 SHA-1 hash to included in notifyCommit **/ - public String notifyCommit(JenkinsRule r, @CheckForNull String notifyCommitToken, @CheckForNull String sha1) throws Exception { + public String notifyCommitWithResults(JenkinsRule r, @CheckForNull String notifyCommitToken, @CheckForNull String sha1) throws Exception { boolean expectError = notifyCommitToken == null || notifyCommitToken.contains(INVALID_NOTIFY_COMMIT_TOKEN); synchronousPolling(r); JenkinsRule.WebClient webClient = r.createWebClient(); From c54ef076130bcb6b0c75ad20abec4cc6dfcef52b Mon Sep 17 00:00:00 2001 From: Mark Waite Date: Mon, 5 Aug 2024 07:07:24 -0600 Subject: [PATCH 4/4] Downgrade matrix-project optional dependency for PCT (#1627) The plugin compatibility tester does not load the version of the optional dependency that is specified by the plugin (git plugin in this case) when loading plugins to test a plugin that depends on the git plugin (pipeline-model-definition in this case). Downgrading this optional dependency should be harmless to other plugins and to users and may allow the plugin compatibility tester to pass tests in the plugin bill of materials. --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 2eddb9dc94..c223583000 100644 --- a/pom.xml +++ b/pom.xml @@ -138,6 +138,9 @@ org.jenkins-ci.plugins matrix-project true + + + 822.824.v14451b_c0fd42 org.jenkins-ci.plugins