Skip to content

Commit c7cb4a9

Browse files
authored
Merge branch 'master' into feature/340-resource-event-listener
2 parents c51d18f + 8561d98 commit c7cb4a9

27 files changed

Lines changed: 532 additions & 40 deletions

File tree

.github/workflows/auto-label-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
runs-on: ubuntu-latest
1717
steps:
1818
- name: Auto-label based on title and branch
19-
uses: actions/github-script@v8
19+
uses: actions/github-script@v9
2020
with:
2121
script: |
2222
const pr = context.payload.pull_request;

.github/workflows/dependabot-auto-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ jobs:
1717
run: gh pr merge --auto --squash "$PR_URL"
1818
env:
1919
PR_URL: ${{ github.event.pull_request.html_url }}
20-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20+
GH_TOKEN: ${{ secrets.GH_TOKEN }}

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ echo 'Finish'
8484
8585
```
8686

87+
#### Lock with a reason
88+
89+
You can specify a reason why the resource is being locked. This is displayed
90+
in the lockable resources UI while the resource is locked:
91+
92+
```groovy
93+
lock(resource: 'staging-server', reason: 'Running integration tests') {
94+
echo 'Deploying to staging'
95+
}
96+
```
97+
98+
The reason helps other users understand why a resource is unavailable.
99+
87100
Example for declarative pipeline:
88101

89102
```groovy

src/main/java/org/jenkins/plugins/lockableresources/LockStep.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public class LockStep extends Step implements Serializable {
4242
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility.")
4343
public String label = null;
4444

45+
/** The reason why this resource is being locked, displayed in the UI while locked. */
46+
@CheckForNull
47+
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility.")
48+
public String reason = null;
49+
4550
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility.")
4651
public int quantity = 0;
4752

@@ -117,6 +122,13 @@ public void setLabel(String label) {
117122
}
118123
}
119124

125+
@DataBoundSetter
126+
public void setReason(String reason) {
127+
if (reason != null && !reason.trim().isEmpty()) {
128+
this.reason = reason.trim();
129+
}
130+
}
131+
120132
@DataBoundSetter
121133
public void setVariable(String variable) {
122134
if (variable != null && !variable.trim().isEmpty()) {
@@ -230,7 +242,7 @@ public String toString() {
230242
.map(res -> "{" + res.toString() + "}")
231243
.collect(Collectors.joining(","));
232244
} else if (resource != null || label != null) {
233-
String ret = LockStepResource.toString(resource, label, quantity);
245+
String ret = LockStepResource.toString(resource, label, quantity, reason);
234246
if (this.priority != 0) {
235247
ret += ", Priority: " + this.priority;
236248
}
@@ -251,7 +263,7 @@ public void validate(boolean allowEmptyOrNullValues) {
251263
public List<LockStepResource> getResources() {
252264
List<LockStepResource> resources = new ArrayList<>();
253265
if (resource != null || label != null) {
254-
resources.add(new LockStepResource(resource, label, quantity));
266+
resources.add(new LockStepResource(resource, label, quantity, reason));
255267
}
256268

257269
if (extra != null) {

src/main/java/org/jenkins/plugins/lockableresources/LockStepExecution.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public boolean start() throws Exception {
9090
return false;
9191
}
9292

93-
if (!lrm.lock(available, run)) {
93+
if (!lrm.lock(available, run, step.reason)) {
9494
// this here is very defensive code, and you will probably never hit it. (hopefully)
9595
LOGGER.warning("Internal program error: Can not lock resources: " + available);
9696
onLockFailed(logger, resourceHolderList);
@@ -156,7 +156,8 @@ private void onLockFailed(PrintStream logger, List<LockableResourcesStruct> reso
156156
step.toString(),
157157
step.variable,
158158
step.inversePrecedence,
159-
step.priority);
159+
step.priority,
160+
step.reason);
160161
}
161162
}
162163

src/main/java/org/jenkins/plugins/lockableresources/LockStepResource.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,20 @@ public class LockStepResource extends AbstractDescribableImpl<LockStepResource>
3535
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility.")
3636
public int quantity = 0;
3737

38+
/** The reason why this resource is being locked, displayed in the UI while locked. */
39+
@CheckForNull
40+
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility.")
41+
public String reason = null;
42+
3843
LockStepResource(@Nullable String resource, @Nullable String label, int quantity) {
44+
this(resource, label, quantity, null);
45+
}
46+
47+
LockStepResource(@Nullable String resource, @Nullable String label, int quantity, @Nullable String reason) {
3948
this.resource = Util.fixEmptyAndTrim(resource);
4049
this.label = Util.fixEmptyAndTrim(label);
4150
this.quantity = quantity;
51+
this.reason = Util.fixEmptyAndTrim(reason);
4252
}
4353

4454
@DataBoundConstructor
@@ -56,24 +66,37 @@ public void setQuantity(int quantity) {
5666
this.quantity = quantity;
5767
}
5868

69+
@DataBoundSetter
70+
public void setReason(String reason) {
71+
this.reason = Util.fixEmptyAndTrim(reason);
72+
}
73+
5974
@Override
6075
public String toString() {
61-
return toString(resource, label, quantity);
76+
return toString(resource, label, quantity, reason);
6277
}
6378

6479
public static String toString(String resource, String label, int quantity) {
80+
return toString(resource, label, quantity, null);
81+
}
82+
83+
public static String toString(String resource, String label, int quantity, String reason) {
6584
// a label takes always priority
85+
StringBuilder sb = new StringBuilder();
6686
if (label != null) {
87+
sb.append("Label: ").append(label);
6788
if (quantity > 0) {
68-
return "Label: " + label + ", Quantity: " + quantity;
89+
sb.append(", Quantity: ").append(quantity);
6990
}
70-
return "Label: " + label;
91+
} else if (resource != null) {
92+
sb.append("Resource: ").append(resource);
93+
} else {
94+
return "[no resource/label specified - probably a bug]";
7195
}
72-
// make sure there is an actual resource specified
73-
if (resource != null) {
74-
return "Resource: " + resource;
96+
if (reason != null && !reason.isEmpty()) {
97+
sb.append(", Reason: ").append(reason);
7598
}
76-
return "[no resource/label specified - probably a bug]";
99+
return sb.toString();
77100
}
78101

79102
// -------------------------------------------------------------------------

src/main/java/org/jenkins/plugins/lockableresources/LockableResource.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public class LockableResource extends AbstractDescribableImpl<LockableResource>
7272
private Date reservedTimestamp = null;
7373
private String note = "";
7474

75+
/**
76+
* The reason why this resource is currently locked. Set via the lock() step's reason parameter.
77+
* Cleared when the resource is unlocked.
78+
*/
79+
private String lockReason = "";
80+
7581
/**
7682
* Track that a currently reserved resource was originally reserved for someone else, or locked
7783
* for some other job, and explicitly taken away - e.g. for SUT post-mortem while a test job runs.
@@ -255,6 +261,26 @@ public void setNote(@Nullable String note) {
255261
this.note = Util.fixNull(note);
256262
}
257263

264+
/**
265+
* Returns the reason why this resource is currently locked.
266+
*
267+
* @return The lock reason, or empty string if not set.
268+
*/
269+
@Exported
270+
public String getLockReason() {
271+
return this.lockReason;
272+
}
273+
274+
/**
275+
* Sets the reason why this resource is being locked. This is typically set via the lock() step's
276+
* reason parameter and cleared when the resource is unlocked.
277+
*
278+
* @param lockReason The reason for locking, or null to clear.
279+
*/
280+
public void setLockReason(@Nullable String lockReason) {
281+
this.lockReason = Util.fixNull(lockReason);
282+
}
283+
258284
@DataBoundSetter
259285
public void setEphemeral(boolean ephemeral) {
260286
this.ephemeral = ephemeral;
@@ -422,6 +448,7 @@ private boolean evaluateScript(@NonNull SecureGroovyScript script, @CheckForNull
422448
binding.setVariable("resourceDescription", description);
423449
binding.setVariable("resourceLabels", this.getLabelsAsList());
424450
binding.setVariable("resourceNote", note);
451+
binding.setVariable("resourceLockReason", lockReason);
425452
try {
426453
Object result = script.evaluate(Jenkins.get().getPluginManager().uberClassLoader, binding, null);
427454
if (LOGGER.isLoggable(Level.FINE)) {
@@ -650,20 +677,27 @@ public boolean isStolen() {
650677
}
651678

652679
public void reserve(String userName) {
680+
reserve(userName, null);
681+
}
682+
683+
public void reserve(String userName, String reason) {
653684
setReservedBy(userName);
654685
setReservedTimestamp(new Date());
686+
setLockReason(reason);
655687
}
656688

657689
public void unReserve() {
658690
this.setReservedBy(null);
659691
this.setReservedTimestamp(null);
692+
this.setLockReason(null);
660693
this.stolen = false;
661694
}
662695

663696
public void reset() {
664697
this.unReserve();
665698
this.unqueue();
666699
this.setBuild(null);
700+
this.setLockReason(null);
667701
invalidateCaches();
668702
}
669703

@@ -678,6 +712,7 @@ public void copyUnconfigurableProperties(final LockableResource sourceResource)
678712
setReservedTimestamp(sourceResource.getReservedTimestamp());
679713
setNote(sourceResource.getNote());
680714
setReservedBy(sourceResource.getReservedBy());
715+
setLockReason(sourceResource.getLockReason());
681716
}
682717
}
683718

@@ -689,6 +724,7 @@ public void resetUnconfigurableProperties() {
689724
setReservedBy(null);
690725
setReservedTimestamp(null);
691726
setNote("");
727+
setLockReason("");
692728
}
693729

694730
/**

0 commit comments

Comments
 (0)