Skip to content

Commit 343ba68

Browse files
committed
Add a hasStash step to detect stashes
1 parent 08edded commit 343ba68

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

vars/hasStash.groovy

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
Returns true if a Pipeline stash with the given name exists for the current build,
3+
false otherwise.
4+
5+
Storage layout matches {@link org.jenkinsci.plugins.workflow.flow.StashManager}:
6+
7+
- Default / on-controller storage: {@code <buildDir>/stashes/<name>.tar.gz}
8+
- {@link org.jenkinsci.plugins.workflow.flow.StashManager.StashAwareArtifactManager}
9+
implementations (including Artifact Manager on S3 / {@code artifact-manager-s3},
10+
which uses {@code io.jenkins.plugins.artifact_manager_jclouds.JCloudsArtifactManager}):
11+
{@code <same prefix as artifacts>/stashes/<name>.tgz} next to the {@code artifacts/}
12+
prefix, exposed through {@link jenkins.util.VirtualFile}.
13+
14+
Fully NonCPS; no agent necessary.
15+
16+
Usage:
17+
{@code
18+
if (hasStash('my-stash')) {
19+
unstash 'my-stash'
20+
}
21+
}
22+
*/
23+
24+
import hudson.model.Run
25+
import jenkins.model.ArtifactManager
26+
import jenkins.model.Jenkins
27+
import jenkins.util.VirtualFile
28+
import org.jenkinsci.plugins.workflow.flow.StashManager
29+
30+
@NonCPS
31+
Boolean existsOnRun(Run run, String name) {
32+
Jenkins.checkGoodName(name)
33+
File local = new File(run.rootDir, "stashes/${name}.tar.gz")
34+
if(local.isFile()) {
35+
return true
36+
}
37+
ArtifactManager am
38+
try {
39+
am = run.pickArtifactManager()
40+
VirtualFile artRoot = am?.root()
41+
if(artRoot == null) {
42+
return false
43+
}
44+
VirtualFile base = artRoot.parent
45+
if(base == null) {
46+
return false
47+
}
48+
// JClouds / S3 stashes use .tgz; local StashManager uses .tar.gz — order avoids extra blob lookups on S3.
49+
List<String> extensions = (am instanceof StashManager.StashAwareArtifactManager) ? ['.tgz', '.tar.gz'] : ['.tar.gz', '.tgz']
50+
for(String ext in extensions) {
51+
VirtualFile candidate = base.child("stashes/${name}${ext}")
52+
try {
53+
if(candidate.exists()) {
54+
return true
55+
}
56+
} catch(Exception ignored) {
57+
// VirtualFile on remote blob stores (e.g. S3) may throw I/O or runtime failures per blob probe.
58+
}
59+
}
60+
} catch(Exception ignored) {
61+
return false
62+
}
63+
false
64+
}
65+
66+
@NonCPS
67+
Boolean call(String name) {
68+
existsOnRun(currentBuild.rawBuild, name)
69+
}

0 commit comments

Comments
 (0)