Giter VIP home page Giter VIP logo

cucumber-living-documentation-plugin's Introduction

Cucumber Living Documentation Plugin for Jenkins

1. Introduction

The Cucumber living documentation plugin basically scans for Cucumber json output files in jenkins workspace in order to generate living documentation from it.

Cucumber json output files are generated after Cucumber test using the json formatter:

@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"json:target/cucumber.json"} )
ℹī¸
plugin option replaced format option which was deprecated in newer cucumber versions.

Here is how a Cucumber feature look like in a documentation:

feature

The feature file for sample above can be found here.

💡
For more example documentations see here.

2. Usage

After instalation the post build action Living documentation must be available on your jobs:

config01

3. Configuration

Here are the possible plugin configuration:

config02

4. Accessing documentation

When Cucumber living documentation plugin is enabled in your job it adds a link which will take you to current project documentation:

initial
ℹī¸
The plugin only stores the last generated documentation.

If you choice format all in configuration then two links will be rendered in the side panel:

all docs
❗

If you face the exception below:

java.lang.ClassCircularityError: org/jruby/RubyClass

you probably hit issue JENKINS-31019, to solve that you need to upgrade your installation to v1.640 or newer.

5. Documentation history

Since version 1.1.1 the plugin stores living documentation history.

docs history
⚠ī¸
It reads the history from your job runs history, if you delete a job execution, the documentation will also be deleted from the history.

6. Jenkins pipeline step

Following is an example of pipeline step using this plugin:

node {
    checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[credentialsId: '', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'https://subversion.assembla.com/svn/cucumber-json-files/trunk']], workspaceUpdater: [$class: 'UpdateUpdater']])
    step([$class: 'CukedoctorPublisher', featuresDir: '', format: 'HTML', hideFeaturesSection: false, hideScenarioKeyword: false, hideStepTime: false, hideSummary: false, hideTags: false, numbered: true, sectAnchors: true, title: 'Living Documentation', toc: 'RIGHT'])
}

Since version 1.0.10 it is possible to use the livingDocs shortcut in pipeline DSL:

node {
    svn 'https://subversion.assembla.com/svn/cucumber-json-files/trunk'
    livingDocs()
}

Parameters should be declared as key: 'value' as example below:

node {
    svn 'https://subversion.assembla.com/svn/cucumber-json-files/trunk'
    livingDocs(featuresDir:'cukedoctor')
}

Or using the declarative pipeline:

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                svn 'https://subversion.assembla.com/svn/cucumber-json-files/trunk'
                livingDocs(featuresDir:'cukedoctor')
            }
        }
    }
}

7. Docker

An easy way to test this plugin is using a docker container, here are the steps (assumming you have docker installed):

  1. Run the image:

    docker run -it -p 8080:8080 rmpestano/jenkins-living-documentation
  2. Access localhot:8080/ and create a job

  3. Configure this svn repository: https://subversion.assembla.com/svn/cucumber-json-files/trunk/

    ℹī¸
    This repository contains cucumber json sample files for the living documentation plugin
  4. Add the Living documentation post build action;

  5. Just run the job

💡
use featuresDir to point to specific json output, eg: /cukedoctor.

Job output should look like:

job output

cucumber-living-documentation-plugin's People

Contributors

glibas avatar markewaite avatar oleg-nenashev avatar rmpestano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cucumber-living-documentation-plugin's Issues

NullPointerException at CukedoctorPublisher

Hi,

I am trying to run a simple pipeline (checkout - build - publisher) with this plugin. The pipeline script is:

node  {
    stage ('Checkout') {
        checkout([$class: 'SubversionSCM',
                                locations: [[credentialsId: '15d0c81b-2be9-45a0-b47b-aca2450c18b9',
                                depthOption: 'infinity',
                                ignoreExternalsOption: true,
                                local: '.',
                                    remote: ****']]])
    }

    stage ('Build') {
        sh '/usr/bin/mvn --batch-mode clean package'
    }

    stage ('Publisher') {
        step([$class: 'CukedoctorPublisher', featuresDir: 'target/surefire-reports/cucumber-json'])
    }
}

But pipeline throws the exception:

[Pipeline] End of Pipeline
java.lang.NullPointerException
        at com.github.cukedoctor.jenkins.CukedoctorPublisher.perform(CukedoctorPublisher.java:150)
        at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:69)
        at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:59)
        at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:52)
        at hudson.security.ACL.impersonate(ACL.java:213)
        at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:49)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE

Environment:

  • Jenkins ver. 1.651.2
  • Cucumber Living Documentation Plugin 1.0.6
  • All pipeline plugins updated

Use Jenkins 2.73 as baseline

Since version 1.1.0 we have updated AsciidoctorJ to latest version which requires jruby 9.x.

Prior to Jenkins 2.73 Jruby 9.x was not supported and the following exception was raised:

java.lang.NoSuchMethodError: jnr.constants.platform.OpenFlags.defined()Z

This was fixed in Jenkins 2.73 by this PR.

SECURITY

Content of this issue removed intentionally.

Generate Cucumber json output file and generate live documentation

I have installed this plugin on Jenkins and I have a pipeline where I run some tests using feature files.

Inside all feature files I inserted the code bellow:

@RunWith(Cucumber.class)
@CucumberOptions(plugin ={"json:target/cucumber.json"})

Is it correct? I cannot find cucumber.json. Is there some way to know if the file was generated?

After that, if I use the code bellow, will I be able to see the live documentation?

stage ('Publisher') {
        step([$class: 'CukedoctorPublisher', featuresDir: 'target/cucumber-json'])
}

Thanks.

File handles leak

Running Jenkins 2.263.3 on ubuntu 14 we noticed that this plugin was causing a file handles leak:

3127 descriptors are open
#1 /tmp/jruby-1136/jruby3454834155092316185parser.jar by thread:pool-5869-thread-1 on Mon Feb 01 18:13:23 EST 2021
	at java.util.zip.ZipFile.<init>(ZipFile.java:156)
	at java.util.jar.JarFile.<init>(JarFile.java:166)
	at java.util.jar.JarFile.<init>(JarFile.java:103)
	at org.jruby.util.JarCache$JarIndex.<init>(JarCache.java:47)
	at org.jruby.util.JarCache.getIndex(JarCache.java:142)
	at org.jruby.util.JarResource.createJarResource(JarResource.java:47)
	at org.jruby.util.JarResource.create(JarResource.java:37)
	at org.jruby.util.URLResource.addDirectoryEntries(URLResource.java:241)
	at org.jruby.util.URLResource.addDirectoriesFromClassloader(URLResource.java:230)
	at org.jruby.util.URLResource.createClassloaderURI(URLResource.java:210)
	at org.jruby.util.URLResource.create(URLResource.java:267)
	at org.jruby.util.JRubyFile.createResource(JRubyFile.java:105)
	at org.jruby.util.JRubyFile.createResource(JRubyFile.java:78)
	at org.jruby.RubyFileTest.exist(RubyFileTest.java:129)
	at org.jruby.RubyFile.realpath(RubyFile.java:900)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:997)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.ir.instructions.DefineModuleInstr.INTERPRET_MODULE(DefineModuleInstr.java:81)
	at org.jruby.ir.instructions.DefineModuleInstr.interpret(DefineModuleInstr.java:69)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.ir.instructions.DefineModuleInstr.INTERPRET_MODULE(DefineModuleInstr.java:81)
	at org.jruby.ir.instructions.DefineModuleInstr.interpret(DefineModuleInstr.java:69)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.ir.instructions.DefineModuleInstr.INTERPRET_MODULE(DefineModuleInstr.java:81)
	at org.jruby.ir.instructions.DefineModuleInstr.interpret(DefineModuleInstr.java:69)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel.require_relative(RubyKernel.java:1002)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require_relative.call(RubyKernel$INVOKER$s$1$0$require_relative.gen)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.runInterpreter(Ruby.java:1218)
	at org.jruby.Ruby.loadFile(Ruby.java:2785)
	at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:887)
	at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:535)
	at org.jruby.runtime.load.LoadService.require(LoadService.java:402)
	at org.jruby.RubyKernel.requireCommon(RubyKernel.java:981)
	at org.jruby.RubyKernel.require(RubyKernel.java:974)
	at org.jruby.RubyKernel$INVOKER$s$1$0$require.call(RubyKernel$INVOKER$s$1$0$require.gen)
	at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:417)
	at org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:97)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:172)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
	at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.Ruby.evalScriptlet(Ruby.java:860)
	at org.jruby.Ruby.evalScriptlet(Ruby.java:836)
	at org.asciidoctor.jruby.internal.RubyUtils.requireLibrary(RubyUtils.java:27)
	at org.asciidoctor.jruby.internal.JRubyAsciidoctor.requireLibraries(JRubyAsciidoctor.java:231)
	at org.asciidoctor.jruby.internal.JRubyAsciidoctor.requireLibrary(JRubyAsciidoctor.java:224)
	at com.github.cukedoctor.CukedoctorMain.execute(CukedoctorMain.java:235)
	at com.github.cukedoctor.jenkins.CukedoctorPublisher.generateDocumentation(CukedoctorPublisher.java:276)
	at com.github.cukedoctor.jenkins.CukedoctorPublisher.lambda$run$1(CukedoctorPublisher.java:260)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Found using the file handles plugin.

Also the links to the living doc are broken (/cucumber-living-documentation/docsHtml/) since we enabled artifact manager on S3 plugin.

Screen Shot 2021-02-03 at 10 50 29 AM

Deprecate Cucumber living documentation plugin

Jenkins and Asciidoctor integration is not straightforward and always caused issues on every jenkins or plugin update. When we updated Cukedoctor (the library used to generate documentation from cucumber features) to Asciidoctor 2.x the Jenkins plugin simply stopped working because Asciidoctor cannot load ruby gems via JRuby, we tried different approaches without success and now we decided to deprecate this plugin and use another tool to publish the cucumber documentation. Details on this issue: rmpestano/cukedoctor#157

The next steps are to follow the process of plugin removal from Jenkins plugin center, described here: https://www.jenkins.io/doc/developer/plugin-governance/deprecating-or-removing-plugin/

Please add a License file

It's not clear what this plugin is licensed under. Can you please add a license file to the repo?

Features are not found

I've got a job configured like this:

Features dir: build/cucumber-results

During the build, the cucumber.json and *.feature files are generated/copied into the above directory.

Here's the output of running only the plugin in the workspace:

Building in workspace /usr/share/tomcat7/.jenkins/workspace/webtest-testing
Fetching changes from the remote Git repository
Checking out Revision c42cbd4c99823486393d1309c29ce3c6c874adc2 (detached)

Generating living documentation for webtest-testing with the following arguments: 
Features dir: /usr/share/tomcat7/.jenkins/workspace/webtest-testing/build/cucumber-results
Format: all
Toc: left
Title: Features
Numbered: true
Section anchors: true

No features Found in /usr/share/tomcat7/.jenkins/jobs/webtest-testing/builds/10/build/cucumber-results. 
Living documentation will not be generated.
Finished: SUCCESS

Here is what is in those dirs:

ls -1 /usr/share/tomcat7/.jenkins/workspace/webtest-testing/build/cucumber-results
cucumber.json

And:

ls -1 /usr/share/tomcat7/.jenkins/workspace/webtest-testing/build/cucumber-results
1560_access.feature
1561_user_account.feature
1613_insert.feature
1639_preview.feature
1697_display.feature
cucumber.json
formatter.js
index.html
jquery-1.8.2.min.js
report.js
style.css

It is a tad confusing that the plugin says it is using Features dir in the workspace, but actually looks for feature files in the job/build directory. Strangely enough, when I manually copy the features into the job/build directory, it still doesn't work.

I also do find it confusing that the 'Features dir' is described as "Directory, relative to workspace, to search for cucumber .json test results. Default value is job workspace." - Why are features and json test results mixed in one directory? Usually features are in workspace/src/features, and the json gets generated inside a build or target dir.

I'm running on a master-only Jenkins, version 2.7.1, with the latest version of the Living Doc plugin.

Simplify pipeline script execution

To call the plugin via pipeline script one needs to declare all parameters and declare the step:

 step([$class: 'CukedoctorPublisher', featuresDir: '', format: 'HTML', hideFeaturesSection: false, hideScenarioKeyword: false, hideStepTime: false, hideSummary: false, hideTags: false, numbered: true, sectAnchors: true, title: 'Living Documentation', toc: 'RIGHT'])

Make livingDocs pipeline step aware as described here.

Jenkins pipeline and behat compatibility ?

Hi,

I am trying to implement your plugin in a Jenkins pipeline.

I added to my Jenkinsfile the following line:

// Generate living documentation
step([$class: 'CukedoctorPublisher', featuresDir: "${_paths.src}/reports/behat", numbered: true, sectAnchors: true, toc: 'RIGHT', format: 'HTML', title: 'Documentation'])

However, the plugin fail without any output, nor in the console output, nor in the Jenkins log.

I successfully use the json file with the slack send plugin.

Could you tell me if this is possible to use this plugin with the new Jenkins 2 pipeline ? is this plugin also compatible with behat tests ?

Thanks

java.nio.file.NoSuchFileException: asciidoctor.css

After upgrading the plugin to the latest version we are getting the following error when we try to view the HTML reports:

java.nio.file.NoSuchFileException: .... /builds/102/cucumber-living-documentation/themes/asciidoctor.css

Any suggestions on what needs to be changed to utilize the latest version of the plugin?

Thanks.

Store documentation history

Currently only last generated documentation is saved, make it possible to browse previously generated documentation by old builds.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤ī¸ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.