diff --git a/README.md b/README.md
index 327130d..6cc17c5 100644
--- a/README.md
+++ b/README.md
@@ -11,3 +11,27 @@ Make sure your Locale is set to en_US, otherwise the expect script wont work as
## Usage
+### Configure RPM signing keys
+* Go to Jenkins >> Manage Jenkins >> Configure System
+* Go to "RPM Signing Keys" section
+* Click on "Add GPG key" button to configure gpg key in jenkins master.
+
+## Option-1: Using Jenkinsfile (or pipeline)
+* Use Jenkins "Pipeline Syntax" (Snippet Generator) to help generate pipeline step.
+* Select "rpmSign: [RPMSign] - Sign RPMs" from "Sample Step" drop down.
+* Set values for "Sign RPMs"
+ * "GPG Key" drop down to select value from the configured GPG keys (mentioned in above section).
+ * "includes" textbox to provide rpm paths (default value is \*\*/target/*.rpm).
+ * "Cmdline Options" for custom options to be passed to rpm command.
+ * "Resign?" checkbox (enable it if resigning of rpm is required).
+* Click on "Generate Pipeline Script"
+* genereated step example:
+ ```
+ rpmSign(rpms: [[gpgKeyName: '121ADA11', includes: 'build/distributions/*.rpm']]])
+ ```
+
+## Option-2: USing Jenkins job configuration
+* Click on "Configure" button of jenkins job.
+* Select "[RPMSign] - Sign RPMs" from "Post-build Action" drop down.
+* Click on "Add RPM" button.
+* Set values for GPG Key, includes, Cmdline Options, and Resign.
diff --git a/pom.xml b/pom.xml
index 696c3f4..ea3ec42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.jenkins-ci.plugins
plugin
- 3.4
+ 3.26
rpmsign-plugin
@@ -14,8 +14,8 @@
UTF-8
- 1.625.3
- 7
+ 2.138.2
+ 8
diff --git a/src/main/java/jenkins/plugins/rpmsign/GpgKey.java b/src/main/java/jenkins/plugins/rpmsign/GpgKey.java
index 2ba0eba..76b9b09 100644
--- a/src/main/java/jenkins/plugins/rpmsign/GpgKey.java
+++ b/src/main/java/jenkins/plugins/rpmsign/GpgKey.java
@@ -35,8 +35,8 @@ public String getId() {
public int getUniqueId() {
int result = name != null ? name.hashCode() : 0;
- result = 31 * result + (privateKey.getPlainText() != null ? privateKey.getPlainText().hashCode() : 0);
- result = 31 * result + (passphrase.getPlainText() != null ? passphrase.getPlainText().hashCode() : 0);
+ result = 31 * result + privateKey.getPlainText().hashCode();
+ result = 31 * result + passphrase.getPlainText().hashCode();
return result;
}
diff --git a/src/main/java/jenkins/plugins/rpmsign/Rpm.java b/src/main/java/jenkins/plugins/rpmsign/Rpm.java
index 494211e..ef8e0b4 100644
--- a/src/main/java/jenkins/plugins/rpmsign/Rpm.java
+++ b/src/main/java/jenkins/plugins/rpmsign/Rpm.java
@@ -4,15 +4,24 @@
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
public class Rpm extends AbstractDescribableImpl {
- private final String gpgKeyName;
- private final String includes;
- private final String cmdlineOpts;
- private final boolean resign;
+ private String gpgKeyName;
+ private String includes;
+ private String cmdlineOpts;
+ private boolean resign;
@DataBoundConstructor
+ public Rpm() {
+ this.gpgKeyName = "";
+ this.includes = "**/**.rpm";
+ this.resign = false;
+ this.cmdlineOpts = "";
+ }
+
+ @Deprecated
public Rpm(String gpgKeyName, String includes, String cmdlineOpts, boolean resign) {
this.gpgKeyName = gpgKeyName;
this.includes = includes;
@@ -36,6 +45,26 @@ public boolean isResign() {
return resign;
}
+ @DataBoundSetter
+ public void setGpgKeyName(final String gpgKeyName) {
+ this.gpgKeyName = gpgKeyName;
+ }
+
+ @DataBoundSetter
+ public void setIncludes(final String includes) {
+ this.includes = includes;
+ }
+
+ @DataBoundSetter
+ public void setCmdlineOpts(final String cmdlineOpts) {
+ this.cmdlineOpts = cmdlineOpts;
+ }
+
+ @DataBoundSetter
+ public void setResign(final boolean resign) {
+ this.resign = resign;
+ }
+
@Extension
public static class DescriptorImpl extends Descriptor {
diff --git a/src/main/java/jenkins/plugins/rpmsign/RpmSignPlugin.java b/src/main/java/jenkins/plugins/rpmsign/RpmSignPlugin.java
index c33f592..681fd86 100644
--- a/src/main/java/jenkins/plugins/rpmsign/RpmSignPlugin.java
+++ b/src/main/java/jenkins/plugins/rpmsign/RpmSignPlugin.java
@@ -1,5 +1,6 @@
package jenkins.plugins.rpmsign;
+import hudson.AbortException;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
@@ -8,6 +9,8 @@
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
+import hudson.model.Run;
+import hudson.model.TaskListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
@@ -16,11 +19,14 @@
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
+import jenkins.tasks.SimpleBuildStep;
import net.sf.json.JSONObject;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
+import org.jenkinsci.Symbol;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
@@ -30,17 +36,23 @@
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
+import javax.annotation.Nonnull;
-public class RpmSignPlugin extends Recorder {
+public class RpmSignPlugin extends Recorder implements SimpleBuildStep {
- private List entries = Collections.emptyList();
+ private List rpms;
@DataBoundConstructor
@SuppressWarnings("unused")
public RpmSignPlugin(List rpms) {
- this.entries = rpms;
- if (this.entries == null) {
- this.entries = Collections.emptyList();
+ setRpms(rpms);
+ }
+
+ @DataBoundSetter
+ public void setRpms(final List rpms) {
+ this.rpms = rpms;
+ if (this.rpms == null) {
+ this.rpms = Collections.emptyList();
}
}
@@ -49,38 +61,38 @@ public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
- private boolean isPerformDeployment(AbstractBuild build) {
+ private boolean isPerformDeployment(final Run, ?> build) {
Result result = build.getResult();
return result == null || result.isBetterOrEqualTo(Result.UNSTABLE);
}
@SuppressWarnings("unused")
- public List getEntries() {
- return entries;
+ public List getRpms() {
+ return rpms;
}
@Override
- public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ public void perform(@Nonnull final Run, ?> build, @Nonnull final FilePath workspace, @Nonnull final Launcher launcher, @Nonnull final TaskListener listener) throws InterruptedException, IOException {
if (isPerformDeployment(build)) {
listener.getLogger().println("[RpmSignPlugin] - Starting signing RPMs ...");
- for (Rpm rpmEntry : entries) {
+ for (Rpm rpmEntry : rpms) {
StringTokenizer rpmGlobTokenizer = new StringTokenizer(rpmEntry.getIncludes(), ",");
GpgKey gpgKey = getGpgKey(rpmEntry.getGpgKeyName());
if (gpgKey == null) {
- throw new InterruptedException("No GPG key is available.");
+ throw new AbortException("No GPG key is available.");
}
if (gpgKey.getPrivateKey().getPlainText().length() > 0) {
listener.getLogger().println("[RpmSignPlugin] - Importing private key");
- importGpgKey(gpgKey.getPrivateKey().getPlainText(), build, launcher, listener);
+ importGpgKey(gpgKey.getPrivateKey().getPlainText(), build, workspace, launcher, listener);
listener.getLogger().println("[RpmSignPlugin] - Imported private key");
}
- if (!isGpgKeyAvailable(gpgKey, build, launcher, listener)) {
+ if (!isGpgKeyAvailable(gpgKey, build, workspace, launcher, listener)) {
listener.getLogger().println("[RpmSignPlugin] - Can't find GPG key: " + rpmEntry.getGpgKeyName());
- return false;
+ throw new AbortException("Can't find GPG key: " + rpmEntry.getGpgKeyName());
}
while (rpmGlobTokenizer.hasMoreTokens()) {
@@ -88,10 +100,6 @@ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListen
listener.getLogger().println("[RpmSignPlugin] - Publishing " + rpmGlob);
- FilePath workspace = build.getWorkspace();
- if (workspace == null) {
- throw new IllegalStateException("Could not get a workspace.");
- }
FilePath[] matchedRpms = workspace.list(rpmGlob);
if (ArrayUtils.isEmpty(matchedRpms)) {
listener.getLogger().println("[RpmSignPlugin] - No RPMs matching " + rpmGlob);
@@ -119,7 +127,7 @@ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListen
int returnCode = proc.join();
if (returnCode != 0) {
listener.getLogger().println(logPrefix + "Failed signing RPM ...");
- return false;
+ throw new AbortException("Failed signing RPM. returnCode: " + returnCode);
}
i++;
}
@@ -131,6 +139,15 @@ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListen
} else {
listener.getLogger().println("[RpmSignPlugin] - Skipping signing RPMs ...");
}
+ }
+
+ @Override
+ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ FilePath workspace = build.getWorkspace();
+ if (workspace == null) {
+ throw new AbortException("Could not get a workspace.");
+ }
+ perform(build, workspace, launcher, listener);
return true;
}
@@ -178,12 +195,12 @@ private byte[] createExpectScriptFile(String signCommand, String passphrase)
return baos.toByteArray();
}
- private void importGpgKey(String privateKey, AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ private void importGpgKey(String privateKey, Run, ?> build, final FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
ArgumentListBuilder command = new ArgumentListBuilder();
command.add("gpg", "--import", "-");
Launcher.ProcStarter ps = launcher.new ProcStarter();
ps = ps.cmds(command).stdout(listener);
- ps = ps.pwd(build.getWorkspace()).envs(build.getEnvironment(listener));
+ ps = ps.pwd(workspace).envs(build.getEnvironment(listener));
try (InputStream is = new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8))) {
ps.stdin(is);
@@ -192,19 +209,19 @@ private void importGpgKey(String privateKey, AbstractBuild, ?> build, Launcher
}
}
- private boolean isGpgKeyAvailable(GpgKey gpgKey, AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
+ private boolean isGpgKeyAvailable(GpgKey gpgKey, Run, ?> build, final FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
ArgumentListBuilder command = new ArgumentListBuilder();
command.add("gpg", "--fingerprint", gpgKey.getName());
Launcher.ProcStarter ps = launcher.new ProcStarter();
ps = ps.cmds(command).stdout(listener);
- ps = ps.pwd(build.getWorkspace()).envs(build.getEnvironment(listener));
+ ps = ps.pwd(workspace).envs(build.getEnvironment(listener));
Proc proc = launcher.launch(ps);
return proc.join() == 0;
}
private GpgKey getGpgKey(String gpgKeyName) {
- Jenkins jenkins = Jenkins.getInstance();
+ Jenkins jenkins = Jenkins.get();
if (jenkins == null) {
throw new IllegalStateException("Could not get a Jenkins instance.");
}
@@ -220,6 +237,7 @@ private GpgKey getGpgKey(String gpgKeyName) {
}
@Extension
+ @Symbol("rpmSign")
@SuppressWarnings("unused")
public static final class GpgSignerDescriptor extends BuildStepDescriptor {
@@ -273,16 +291,7 @@ public FormValidation doCheckPassphrase(@AncestorInPath AbstractProject project,
}
public FormValidation doCheckIncludes(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException, InterruptedException {
- FilePath workspace = project.getSomeWorkspace();
- if (workspace != null) {
- String msg = workspace.validateAntFileMask(value);
- if (msg != null) {
- return FormValidation.error(msg);
- }
return FormValidation.ok();
- } else {
- return FormValidation.warning(Messages.noworkspace());
- }
}
}
diff --git a/src/main/resources/jenkins/plugins/rpmsign/RpmSignPlugin/config.jelly b/src/main/resources/jenkins/plugins/rpmsign/RpmSignPlugin/config.jelly
index eda7365..41743ab 100644
--- a/src/main/resources/jenkins/plugins/rpmsign/RpmSignPlugin/config.jelly
+++ b/src/main/resources/jenkins/plugins/rpmsign/RpmSignPlugin/config.jelly
@@ -3,7 +3,7 @@
-
+