Navigation Menu

Skip to content

Commit

Permalink
JENKINS-40816
Browse files Browse the repository at this point in the history
Db doc generation
documentation regarding documenttion generation
  • Loading branch information
prospero238 committed Jan 5, 2017
1 parent 693a367 commit c1aae6e
Show file tree
Hide file tree
Showing 17 changed files with 380 additions and 56 deletions.
3 changes: 2 additions & 1 deletion src/docs/1.2.0-release-notes.md
Expand Up @@ -7,5 +7,6 @@ This version now uses the [Credentials Plugin](https://wiki.jenkins-ci.org/displ

* [JENKINS-40707 Pipeline Support](https://issues.jenkins-ci.org/browse/JENKINS-40707)
* [JENKINS-33401 Credentials Integration](https://issues.jenkins-ci.org/browse/JENKINS-33401)
* [JENKINS-40816 Provide liquibase dbdoc generation build step](https://issues.jenkins-ci.org/browse/JENKINS-40816)


51 changes: 9 additions & 42 deletions src/docs/confluence.txt
Expand Up @@ -43,50 +43,15 @@ The rollback build step invokes liquibase's "rollback" operation on the target d

This build step is intended for use when you're deploying to a real environment, and the need arises to undo a previous liquibase update.

h2. Pipeline Support

Both the plugin's update and rollback operations are available to pipline scripts. To evaulate changesets, the syntax
is as follows:

liquibaseUpdate()

Available parameters:
testRollbacks
tagOnSuccessfulBuild
dropAll.

Roll back operations may be done thusly:

liquibasaeRollback()
h2. DbDoc Generation

Available parameters:
This build step generates Liquibase's dbDoc based on the supplied changelog. See [liquibase documentation|http://www.liquibase.org/dbdoc/index.html].

rollbackCount
rollbackToTag
rollbackToDate
rollbackLastHours
It is recommended to use this in conjunction with the [HTMLPublisher plugin|https://wiki.jenkins-ci.org/display/JENKINS/HTML+Publisher+Plugin]

h2. Pipeline Support



Common to each operation are the following parameters:
databaseEngine: Can be set to "MySQL", "PostgreSQL", "Derby", "H2", or "Hypersonic". Providing this value
eliminates the need to supply driverClassname.
credentialsId: The ID of the Jenkins credentials to use when the database requires username & password
changeLogFile: Path to the change log file
url: Database JDBC URL
See liquibase execution for an explaination for these configuration elements:
defaultSchemaName
contexts
liquibasePropertiesPath
classpath
driverClassname
labels
changeLogParameters
basePath

Supplying only "changeLogFile" will cause the buildstep to use an H2 in-memory database.

All liquibase operations are available to pipeline scripts. See [documentation|https://github.com/jenkinsci/liquibase-runner-plugin/blob/develop/src/docs/pipeline.md] for information and examples.

h2. Usage Tips

Expand All @@ -97,11 +62,13 @@ build slave runs your project, that file will no longer be available, and all ch

h3. Version History

h4. Version 1.2.0
h4. Version 1.2.0 (Jan 5, 2017)

* Credentials integration
* [JENKINS-33401|https://issues.jenkins-ci.org/browse/JENKINS-33401] Credentials Integration
* [JENKINS-40816|https://issues.jenkins-ci.org/browse/JENKINS-40816 ] Provide liquibase dbdoc generation build step
* [JENKINS-40707|https://issues.jenkins-ci.org/browse/JENKINS-40707] Pipeline Support


h4. Version 1.1.0 (Aug 25, 2016)

Thanks to David Siegal for suggestions, testing, and guidance for this release.
Expand Down
20 changes: 20 additions & 0 deletions src/docs/pipeline.md
Expand Up @@ -56,3 +56,23 @@ node {
)
}
```

DbDoc Generation
-----------------

```
node {
liquibaseDbDoc( changeLogFile: 'changeset.yml', // same basic configuration parameters
url: 'jdbc:postgresql://localhost:5432/sample-db',
driverClassname: 'org.postgresql.Driver',
outputDirectory: 'dbdoc')
// works great with the HTML publisher plugin (sold separately)
publishHTML(target: [reportDir : 'dbdoc',
reportFiles: 'index.html',
reportName : 'DbDoc',
keepAll : true])
}
```
Expand Up @@ -103,7 +103,9 @@ public abstract void runPerform(Run<?, ?> build,
TaskListener listener,
Liquibase liquibase,
Contexts contexts,
LabelExpression labelExpression, ExecutedChangesetAction executedChangesetAction)
LabelExpression labelExpression,
ExecutedChangesetAction executedChangesetAction,
FilePath workspace)
throws InterruptedException, IOException, LiquibaseException;

abstract public Descriptor<Builder> getDescriptor();
Expand All @@ -125,14 +127,14 @@ public void perform(@Nonnull Run<?, ?> build,
new LabelExpression(getProperty(configProperties, LiquibaseProperty.LABELS));

try {
runPerform(build, listener, liquibase, contexts, labelExpression, executedChangesetAction);
runPerform(build, listener, liquibase, contexts, labelExpression, executedChangesetAction, workspace);
} catch (LiquibaseException e) {
e.printStackTrace(listener.getLogger());
build.setResult(Result.UNSTABLE);
} finally {
closeLiquibase(liquibase);
}
if (!executedChangesetAction.isRollbackOnly()) {
if (!executedChangesetAction.isNoExecutionsExpected()) {
build.addAction(executedChangesetAction);
}
}
Expand Down Expand Up @@ -388,4 +390,6 @@ public String getCredentialsId() {
public void setCredentialsId(String credentialsId) {
this.credentialsId = credentialsId;
}


}
@@ -1,6 +1,7 @@
package org.jenkinsci.plugins.liquibase.evaluator;

import hudson.Extension;
import hudson.FilePath;
import hudson.model.AbstractProject;
import hudson.model.Descriptor;
import hudson.model.Result;
Expand Down Expand Up @@ -43,7 +44,9 @@ public void runPerform(Run<?, ?> build,
TaskListener listener,
Liquibase liquibase,
Contexts contexts,
LabelExpression labelExpression, ExecutedChangesetAction executedChangesetAction) {
LabelExpression labelExpression,
ExecutedChangesetAction executedChangesetAction,
FilePath workspace) {

executedChangesetAction.setRollbacksTested(testRollbacks);

Expand Down
@@ -0,0 +1,118 @@
package org.jenkinsci.plugins.liquibase.evaluator;

import hudson.Extension;
import hudson.FilePath;
import hudson.model.AbstractProject;
import hudson.model.Descriptor;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.remoting.VirtualChannel;
import hudson.tasks.Builder;
import liquibase.Contexts;
import liquibase.LabelExpression;
import liquibase.Liquibase;
import liquibase.exception.LiquibaseException;

import java.io.File;
import java.io.IOException;

import org.jenkinsci.remoting.RoleChecker;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

public class DatabaseDocBuilder extends AbstractLiquibaseBuilder {

private String outputDirectory;

@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

@DataBoundConstructor
public DatabaseDocBuilder(String outputDirectory) {
this.outputDirectory = outputDirectory;
}

@Override
public void runPerform(Run<?, ?> build,
TaskListener listener,
Liquibase liquibase,
Contexts contexts,
LabelExpression labelExpression,
ExecutedChangesetAction executedChangesetAction, FilePath workspace)
throws InterruptedException, IOException, LiquibaseException {


executedChangesetAction.setNoExecutionsExpected(true);
FilePath filePath = workspace.child(outputDirectory);

listener.getLogger().println("Generating Liquibase dbDoc in directory '" + outputDirectory + "'");

FilePath.FileCallable callable = new DatabaseDocGenerationCallback(liquibase, contexts, labelExpression);

filePath.act(callable);

}
private static class DatabaseDocGenerationCallback implements FilePath.FileCallable<Void> {

Liquibase liquibase;
Contexts contexts;
LabelExpression labelExpression;

public DatabaseDocGenerationCallback(Liquibase liquibase, Contexts contexts, LabelExpression labelExpression) {
this.liquibase = liquibase;
this.contexts = contexts;
this.labelExpression = labelExpression;
}

@Override
public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
f.mkdirs();
try {
liquibase.generateDocumentation(f.getAbsolutePath(), contexts, labelExpression);
} catch (LiquibaseException e) {
throw new IOException("Error generating documentation", e);
}
return null;
}

@Override
public void checkRoles(RoleChecker roleChecker) throws SecurityException {

}
}

@DataBoundSetter
public void setOutputDirectory(String outputDirectory) {
this.outputDirectory = outputDirectory;
}

public String getOutputDirectory() {
return outputDirectory;
}

@Override
public Descriptor<Builder> getDescriptor() {
return DESCRIPTOR;
}

public static class DescriptorImpl extends AbstractLiquibaseDescriptor {

public DescriptorImpl() {
load();
}

public DescriptorImpl(Class<? extends DatabaseDocBuilder> clazz) {
super(clazz);
}

@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}

@Override
public String getDisplayName() {
return "Generate Liquibase dbDoc";
}
}
}
Expand Up @@ -26,7 +26,7 @@ public class ExecutedChangesetAction implements Action {

private List<ChangeSetDetail> rolledBackChangesets = Lists.newArrayList();

private boolean rollbackOnly;
private boolean noExecutionsExpected;

private String appliedTag;

Expand Down Expand Up @@ -179,11 +179,11 @@ public void setRolledBackChangesets(List<ChangeSetDetail> rolledBackChangesets)
}


public void setRollbackOnly(boolean rollbackOnly) {
this.rollbackOnly = rollbackOnly;
public void setNoExecutionsExpected(boolean noExecutionsExpected) {
this.noExecutionsExpected = noExecutionsExpected;
}

public boolean isRollbackOnly() {
return rollbackOnly;
public boolean isNoExecutionsExpected() {
return noExecutionsExpected;
}
}
Expand Up @@ -2,6 +2,7 @@

import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Util;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
Expand Down Expand Up @@ -56,8 +57,10 @@ public void runPerform(Run<?, ?> build,
TaskListener listener,
Liquibase liquibase,
Contexts contexts,
LabelExpression labelExpression, ExecutedChangesetAction executedChangesetAction) throws InterruptedException, IOException, LiquibaseException {
executedChangesetAction.setRollbackOnly(true);
LabelExpression labelExpression,
ExecutedChangesetAction executedChangesetAction,
FilePath workspace) throws InterruptedException, IOException, LiquibaseException {
executedChangesetAction.setNoExecutionsExpected(true);
RolledbackChangesetAction action = new RolledbackChangesetAction(build);
RollbackStrategy rollbackStrategy = RollbackStrategy.valueOf(rollbackType);
build.addAction(action);
Expand Down
@@ -0,0 +1,67 @@
package org.jenkinsci.plugins.liquibase.workflow;

import hudson.Extension;
import hudson.model.Project;
import hudson.util.ListBoxModel;

import javax.annotation.Nonnull;

import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials;

import static com.cloudbees.plugins.credentials.CredentialsMatchers.anyOf;
import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf;

public class DbDocBuildStep extends AbstractLiquibaseStep {
private String outputDirectory = "";


@DataBoundConstructor
public DbDocBuildStep(String changeLogFile) {
super(changeLogFile);
}

@DataBoundSetter
public void setOutputDirectory(String outputDirectory) {
this.outputDirectory = outputDirectory;
}

public String getOutputDirectory() {
return outputDirectory;
}


@Extension
public static final class DescriptorImpl extends AbstractStepDescriptorImpl {

public DescriptorImpl() {
super(DbDocExecution.class);
}

@Override
public String getFunctionName() {
return "liquibaseDbDoc";
}

@Nonnull
@Override
public String getDisplayName() {
return "Generate Liquibase DbDoc";
}

public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Project project) {
return new StandardListBoxModel()
.withEmptySelection()
.withMatching(anyOf(
instanceOf(UsernamePasswordCredentials.class)),
CredentialsProvider.lookupCredentials(StandardUsernameCredentials.class, project));
}
}
}

0 comments on commit c1aae6e

Please sign in to comment.