Skip to content

Commit

Permalink
[FIXED JENKINS-39394] Renamed "postBuild" to "post".
Browse files Browse the repository at this point in the history
Also moved ast-schema.json to pipeline-model-api, where it should be.
  • Loading branch information
abayer committed Nov 2, 2016
1 parent d954650 commit 567066b
Show file tree
Hide file tree
Showing 33 changed files with 220 additions and 91 deletions.
12 changes: 12 additions & 0 deletions pipeline-model-api/pom.xml
Expand Up @@ -38,6 +38,18 @@
<url>https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Model+Definition+Plugin</url>

<dependencies>
<!-- JSON schema stuff -->
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.2.3</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
@@ -0,0 +1,79 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition;

import com.github.fge.jsonschema.exceptions.ProcessingException;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import hudson.Extension;
import hudson.model.RootAction;
import hudson.util.TimeUnit2;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import java.io.IOException;

/**
* Endpoint for exposing the AST JSON schema.
*
* @author Andrew Bayer
*/
@Extension
public class ASTSchema implements RootAction {
public static final String AST_SCHEMA_URL = "pipeline-model-schema";

@Override
public String getUrlName() {
return AST_SCHEMA_URL;
}

@Override
public String getIconFileName() {
return null;
}

@Override
public String getDisplayName() {
return null;
}

@SuppressWarnings("unused")
public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
rsp.serveFile(req, getClass().getResource("/ast-schema.json"), TimeUnit2.DAYS.toMillis(1));
}

/**
* Get the Pipeline Config AST JSON schema.
*
* @return the schema in {@link JsonSchema} form.
* @throws ProcessingException
*/
public static JsonSchema getJSONSchema() throws ProcessingException {
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
return factory.getJsonSchema("resource:/ast-schema.json");
}

}
Expand Up @@ -29,7 +29,7 @@ public ModelASTPipelineDef(Object sourceLocation) {
public JSONObject toJSON() {
JSONObject a = new JSONObject();
a.put("stages", stages != null ? stages.toJSON() : null);
a.put("postBuild", postBuild != null ? postBuild.toJSON() : null);
a.put("post", postBuild != null ? postBuild.toJSON() : null);
a.put("environment", environment != null ? environment.toJSON() : null);
a.put("agent", agent != null ? agent.toJSON() : null);
a.put("tools", tools != null ? tools.toJSON() : null);
Expand Down Expand Up @@ -276,7 +276,7 @@ public void setWrappers(ModelASTWrappers wrappers) {
public String toString() {
return "ModelASTPipelineDef{" +
"stages=" + stages +
", postBuild=" + postBuild +
", post=" + postBuild +
", environment=" + environment +
", agent=" + agent +
", tools=" + tools +
Expand Down
Expand Up @@ -15,7 +15,7 @@ public ModelASTPostBuild(Object sourceLocation) {

@Override
public java.lang.String getName() {
return "postBuild";
return "post";
}

@Override
Expand Down
Expand Up @@ -289,7 +289,7 @@
}
]
},
"postBuild": {
"post": {
"description": "An array of build conditions with blocks of steps to run if those conditions are satisfied at the end of the build while still on the image/node the build ran on",
"type": "object",
"properties": {
Expand Down Expand Up @@ -317,7 +317,7 @@
"$ref": "#/definitions/agent"
},
"post": {
"$ref": "#/definitions/postBuild"
"$ref": "#/definitions/post"
},
"tools": {
"$ref": "#/definitions/tools"
Expand Down Expand Up @@ -352,8 +352,8 @@
"stages": {
"$ref": "#/definitions/stages"
},
"postBuild": {
"$ref": "#/definitions/postBuild"
"post": {
"$ref": "#/definitions/post"
},
"environment": {
"$ref": "#/definitions/environment"
Expand Down
@@ -0,0 +1,89 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition;

import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.JenkinsRule;

import java.io.IOException;
import java.net.URL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeTrue;

public class ASTSchemaTest {
@ClassRule
public static BuildWatcher buildWatcher = new BuildWatcher();
@ClassRule
public static JenkinsRule j = new JenkinsRule();

@Test
public void doSchema() throws Exception {
JenkinsRule.WebClient wc = j.createWebClient();
String rawSchema = wc.goTo(ASTSchema.AST_SCHEMA_URL + "/json", "application/json").getWebResponse().getContentAsString();
assertNotNull(rawSchema);
JSONObject remoteSchema = JSONObject.fromObject(rawSchema);
assertNotNull(remoteSchema);
assertFalse(remoteSchema.isEmpty());
assertFalse(remoteSchema.isNullObject());

String rawInternalSchema = fileContentsFromResources("ast-schema.json");
assertNotNull(rawInternalSchema);
JSONObject internalSchema = JSONObject.fromObject(rawInternalSchema);

assertNotNull(internalSchema);
assertFalse(internalSchema.isEmpty());
assertFalse(internalSchema.isNullObject());

assertEquals(internalSchema, remoteSchema);
}

protected String fileContentsFromResources(String fileName) throws IOException {
return fileContentsFromResources(fileName, false);
}

protected String fileContentsFromResources(String fileName, boolean swallowError) throws IOException {
String fileContents = null;

URL url = getClass().getResource("/" + fileName);
if (url != null) {
fileContents = IOUtils.toString(url);
}

if (!swallowError) {
assertNotNull("No file contents for file " + fileName, fileContents);
} else {
assumeTrue(fileContents != null);
}
return fileContents;

}
}
14 changes: 1 addition & 13 deletions pipeline-model-definition/pom.xml
Expand Up @@ -112,19 +112,7 @@
<version>1.22</version>
</dependency>

<!-- JSON schema stuff -->
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.2.3</version>
</dependency>

<!-- TEST deps -->
<!-- TEST deps -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git</artifactId>
Expand Down
Expand Up @@ -46,7 +46,7 @@ public class Root implements NestedModel, Serializable {
Stages stages

@Whitelisted
PostBuild postBuild
PostBuild post

@Whitelisted
Environment environment
Expand All @@ -73,8 +73,8 @@ public class Root implements NestedModel, Serializable {
}

@Whitelisted
Root postBuild(PostBuild p) {
this.postBuild = p
Root post(PostBuild p) {
this.post = p
return this
}

Expand Down Expand Up @@ -147,7 +147,7 @@ public class Root implements NestedModel, Serializable {
*/
@Whitelisted
List<Closure> satisfiedPostBuilds(Object runWrapperObj) {
return satisfiedConditionsForField(postBuild, runWrapperObj)
return satisfiedConditionsForField(post, runWrapperObj)
}

@Override
Expand Down
Expand Up @@ -28,14 +28,14 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule
import com.github.fge.jsonschema.exceptions.ProcessingException
import com.github.fge.jsonschema.main.JsonSchema
import com.github.fge.jsonschema.main.JsonSchemaFactory
import com.github.fge.jsonschema.report.ProcessingReport
import net.sf.json.JSONObject
import org.apache.commons.lang.reflect.FieldUtils
import org.codehaus.groovy.control.CompilationFailedException
import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
import org.jenkinsci.plugins.pipeline.modeldefinition.ASTSchema
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPipelineDef
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep
import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution
Expand Down Expand Up @@ -66,7 +66,7 @@ public class Converter {
public static ProcessingReport validateJSONAgainstSchema(JSONObject origJson) throws ProcessingException {
JsonNode jsonNode = jacksonJSONFromJSONObject(origJson);

JsonSchema schema = getJSONSchema();
JsonSchema schema = ASTSchema.getJSONSchema();

return schema.validate(jsonNode)
}
Expand All @@ -84,18 +84,6 @@ public class Converter {
return mapper.valueToTree(input);
}


/**
* Get the Pipeline Config AST JSON schema.
*
* @return the schema in {@link JsonSchema} form.
* @throws ProcessingException
*/
public static JsonSchema getJSONSchema() throws ProcessingException {
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
return factory.getJsonSchema("resource:/ast-schema.json");
}

/**
* Converts a script at a given URL into {@link ModelASTPipelineDef}
*
Expand Down
Expand Up @@ -127,8 +127,8 @@ class JSONParser {
case 'agent':
pipelineDef.agent = parseAgent(pipelineJson.get("agent"))
break
case 'postBuild':
pipelineDef.postBuild = parsePostBuild(pipelineJson.getJSONObject("postBuild"))
case 'post':
pipelineDef.postBuild = parsePostBuild(pipelineJson.getJSONObject("post"))
break
case 'tools':
pipelineDef.tools = parseTools(pipelineJson.getJSONArray("tools"))
Expand Down
Expand Up @@ -172,7 +172,7 @@ class ModelParser {
case 'environment':
r.environment = parseEnvironment(stmt);
break;
case 'postBuild':
case 'post':
r.postBuild = parsePostBuild(stmt);
break;
case 'agent':
Expand All @@ -196,6 +196,9 @@ class ModelParser {
case 'notifications':
errorCollector.error(r, "The 'notifications' section has been removed as of version 0.6. Use 'post' for all post-build actions.")
break
case 'postBuild':
errorCollector.error(r, "The 'postBuild' section has been renamed as of version 0.6. Use 'post' for all post-build actions.")
break
default:
// We need to check for unknowns here.
errorCollector.error(r, "Undefined section '$name'")
Expand Down
Expand Up @@ -102,7 +102,7 @@ class ModelValidatorImpl implements ModelValidator {
}

public boolean validateElement(@Nonnull ModelASTPostBuild postBuild) {
// postBuild specific validation
// post specific validation
true
}

Expand Down

0 comments on commit 567066b

Please sign in to comment.