Jenkins API documentation with phpdox - jenkins

The API MyProject link ( generated by the HTML Publisher Jenkins plugin ) gives 404.
Problem accessing /job/MyProject /API_MyProject/index.html. Reason: Not found
I checked the inputs from the configuration section, in the job item, and in the Publish HTML reports configuration I see the following:
HTML directory to archive: build/api
Index page[s]: index.html
Report title: API MyProject
the url which kicks me to the api documentation, is the following:
http://jenkins.dev:8080/job/MyProject/API_MyProject/
then, I checked if documentation is generated in the build/api folder and I see two folders:
docs/ xml/
there is no index.html, but whether I generated manually a dummy index.html file I still get the same error... another weird behaviour is when I edit the Report title, it changes the link to the still not found api docs..
phpdox.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://xml.phpdox.net/config" silent="false">
<project name="MyProject" source="${basedir}/protected/models" workdir="${basedir}/build/api/xml">
<collector publiconly="false">
<include mask="*.php" />
</collector>
<generator output="${basedir}/build/api/docs">
<build engine="html" enabled="true" output="api">
<file extension="html" />
</build>
</generator>
</project>
</phpdox>
Jenkins final Console output:
phpdox:
[exec] phpDox 0.7.0 - Copyright (C) 2010 - 2014 by Arne Blankerts
[exec]
[exec] [26.12.2014 - 05:57:27] Using config file './phpdox.xml'
[exec] [26.12.2014 - 05:57:27] Registered collector backend 'parser'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'build'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'git'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'checkstyle'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'phpcs'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'pmd'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'phpunit'
[exec] [26.12.2014 - 05:57:27] Registered enricher 'phploc'
[exec] [26.12.2014 - 05:57:27] Registered output engine 'xml'
[exec] [26.12.2014 - 05:57:27] Registered output engine 'html'
[exec] [26.12.2014 - 05:57:27] Starting to process project 'MyProject'
[exec] [26.12.2014 - 05:57:27] Starting collector
[exec] [26.12.2014 - 05:57:27] Scanning directory '/var/lib/jenkins/jobs/MyProject/workspace/protected/models' for files to process
[exec]
[exec] ................ [16]
[exec]
[exec] [26.12.2014 - 05:57:34] Saving results to directory '/var/lib/jenkins/jobs/MyProject/workspace/build/api/xml'
[exec] [26.12.2014 - 05:57:39] Resolving inheritance
[exec]
[exec] ................ [16]
[exec]
[exec] [26.12.2014 - 05:57:39] The following unit(s) had missing dependencies during inheritance resolution:
[exec] [26.12.2014 - 05:57:39] - Category (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] - LoginForm (missing CFormModel)
[exec] [26.12.2014 - 05:57:39] - Mimetype (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] - ContactForm (missing CFormModel)
[exec] [26.12.2014 - 05:57:39] - File (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] - UserAccountReference (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] - Currency (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] - Account (missing CActiveRecord)
[exec] [26.12.2014 - 05:57:39] Collector process completed
[exec]
[exec] [26.12.2014 - 05:57:39] Starting generator
[exec] [26.12.2014 - 05:57:39] Loading enrichers
[exec] [26.12.2014 - 05:57:39] Starting event loop.
[exec]
[exec] .................................................. [50]
[exec] .................................................. [100]
[exec] .................................................. [150]
[exec] .................................................. [200]
[exec] .................................................. [250]
[exec] ............ [262]
[exec]
[exec] [26.12.2014 - 05:57:41] Generator process completed
[exec] [26.12.2014 - 05:57:41] Processing project 'MyProject' completed.
[exec]
[exec]
[exec] Time: 13 seconds, Memory: 12.75Mb
[exec]
build:
BUILD SUCCESSFUL
Total time: 1 minute 57 seconds
[CHECKSTYLE] Collecting checkstyle analysis files...
[CHECKSTYLE] Finding all files that match the pattern build/logs/checkstyle.xml
[CHECKSTYLE] Parsing 1 file in /var/lib/jenkins/jobs/MyProject/workspace
[CHECKSTYLE] Successfully parsed file /var/lib/jenkins/jobs/MyProject/workspace/build/logs/checkstyle.xml with 67 unique warnings and 0 duplicates.
[PMD] Collecting PMD analysis files...
[PMD] Finding all files that match the pattern build/logs/pmd.xml
[PMD] Parsing 1 file in /var/lib/jenkins/jobs/MyProject/workspace
[PMD] Successfully parsed file /var/lib/jenkins/jobs/MyProject/workspace/build/logs/pmd.xml with 61 unique warnings and 0 duplicates.
[DRY] Collecting duplicate code analysis files...
[DRY] Finding all files that match the pattern build/logs/pmd-cpd.xml
[DRY] Parsing 1 file in /var/lib/jenkins/jobs/MyProject/workspace
[DRY] Successfully parsed file /var/lib/jenkins/jobs/MyProject/workspace/build/logs/pmd-cpd.xml with 0 unique warnings and 0 duplicates.
Recording plot data
Publishing Clover coverage report...
Clover xml file does not exist in: /var/lib/jenkins/jobs/MyProject/workspace called: build/logs/clover.xml and will not be copied to: /var/lib/jenkins/jobs/MyProject/builds/2014-12-26_11-55-21/cloverphp/clover.xml
Could not find 'build/coverage/build/logs/clover.xml'. Did you generate the XML report for Clover?
[htmlpublisher] Archiving HTML reports...
[htmlpublisher] Archiving at BUILD level /var/lib/jenkins/jobs/MyProject/workspace/build/api to /var/lib/jenkins/jobs/MyProject/builds/2014-12-26_11-55-21/htmlreports/API_Unnamed
[JDepend] JDepend plugin is ready
[JDepend] Found 16 classes in 2 packages
Finished: SUCCESS

Having just faced a similar problem I checked the skeleton phpdox.xml that the component generates as a guide when you run phpdox --skel.
The included documentation will help you understand what is wrong with your configuration
The way it is configured now, the documentation is generated inside the directory ${basedir}/build/api/docs/api because the build->output parameter is appended to the generator->output url
So in order for jenkins to find the documentation and copy it to the htmlreports folder you need to set the above directory as the "HTML directory to archive" in your project configuration->html reports
My configuration that works is the following:
<generator output="${basedir}/build">
<build engine="html" enabled="true" output="api">
and in project configuration "HTML directory to archive":"app/build/api"
In case your configuration is not the problem check if an index.html file exists in the output directory, because I think that phpdox generates an index.xhtml by default instead. If this is the case you can also change it in the configuration
<build engine="html" enabled="true" output="api">
<file extension="xhtml" />
</build>
change xhtml to html

Related

Malformed Collection Error

Moving on from the first issue I reported here :
Running an OS command using apache-ant to IIS config
I am trying to run the second part of the IIS config.
<exec executable="cmd.exe" dir="C:/Windows/System32/inetsrv"
failonerror="true">
<arg line="/c appcmd set config /section:handlers
/[name=&apos;ExtensionlessUrlHandler-Integrated-
4.0&apos;].verb:GET,POST,PUT,DELETE,OPTIONS,CONNECT"/>
</exec>
I have no double quotes in this line, and I am using apos; to indicate my single quotes. However I'm getting the following error which Im struggling to find an explanation for :
confIIS:
[echo] Configuring IIS
[exec] ERROR ( message:Malformed collection indexer; format is
[#position,name='value',name2='value2',...]. The #position specifier is
optional, and be '#start', '#end', or
#N' where N is a numeric index into the collection. )
quick Update :
I've tried dbl quotes but no luck. I've done some more digging and the issue is that the single quotes are being dropped.
If I run the cmd line in the dos prompt without the single quotes it fails in the same way.
cmd line :
appcmd set config /section:handlers /[name='ExtensionlessUrlHandler-
Integrated-4.0'].verb:GET
Ant script (debug) output
[exec] 'appcmd'
[exec] 'set'
[exec] 'config'
[exec] '/section:handlers'
[exec] '/[name=ExtensionlessUrlHandler-Integrated-
4.0].verb:GET,POST,PUT,DELETE,OPTIONS,CONNECT'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
ute:Java13CommandLauncher: Executing 'cmd.exe' with arguments:

flexmojos-maven-plugin:7.0.1:test-compile build failure at net.flexmojos.oss.unitestingsupport.TestApplication

I have a project with Flexmojos 4.0-beta-7 and multiple modules.
There is an artifact with swc packaging and some tests.
During maven install phase it creates the following MXML file
/target/test-classes/TestRunner.mxml
<?xml version="1.0" encoding="utf-8"?>
<unitestingsupport:TestApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:unitestingsupport="net.flexmojos.oss.unitestingsupport.*"
layout="absolute"
initialize="init()"
port="59896"
controlPort="59895"
>
<mx:Script>
<![CDATA[
import projekt.service.command.CommandServiceTest; CommandServiceTest;
import projekt.service.command.impl.CommandTest; CommandTest;
import projekt.service.console.ConsoleLogTargetTest; ConsoleLogTargetTest;
import projekt.service.dump.dumper.ServiceDumperTest; ServiceDumperTest;
private function init():void {
addTest( CommandServiceTest);
addTest( CommandTest);
addTest( ConsoleLogTargetTest);
addTest( ServiceDumperTest);
}
]]>
</mx:Script>
</unitestingsupport:TestApplication>
So the phase on Flexmojos 4.0-beta-7 runs fine, producing the following output.
[exec] [INFO] --- flexmojos-maven-plugin:4.0-beta-7:test-compile (default-test-compile) # Projekt ---
[exec] [INFO] Flexmojos 4.0-beta-7
[exec] [INFO] Apache License - Version 2.0 (NO WARRANTY) - See COPYRIGHT file
[exec] [INFO] Compiling test class: [projekt.service.command.CommandServiceTest, projekt.service.command.impl.CommandTest, projekt.service.console.ConsoleLogTargetTest, projekt.service.dump.dumper.ServiceDumperTest]
[exec] Writing configuration dump to C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner-configs.xml
[exec] C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner.swf (1181091 bytes)
[exec] [INFO]
[exec] [INFO] --- flexmojos-maven-plugin:4.0-beta-7:test-run (default-test-run) # Projekt ---
But then I have had to upgrade it to Flexmojos 7.0.1 because of FLEXMOJOS-886
https://flexmojos.atlassian.net/browse/FLEXMOJOS-886
Unfortunately, it breaks the phase, producing the following output.
Initially it begins the same way
[exec] [INFO] --- flexmojos-maven-plugin:7.0.1:test-compile (default-test-compile) # Projekt ---
[exec] [INFO] Flexmojos 7.0.1
[exec] [INFO] GPL License - Version 2.0 (NO WARRANTY) - See COPYRIGHT file
[exec] [INFO] Compiling test class: [projekt.service.command.CommandServiceTest, projekt.service.command.impl.CommandTest, projekt.service.console.ConsoleLogTargetTest, projekt.service.dump.dumper.ServiceDumperTest]
But then it fails with the following messages.
Writing configuration dump to C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner-configs.xml
C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner.mxml(30): Error: Cannot resolve attribute 'layout' for component type net.flexmojos.oss.unitestingsupport.TestApplication.
C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner.mxml(30): Error: Cannot resolve attribute 'initialize' for component type net.flexmojos.oss.unitestingsupport.TestApplication.
C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner.mxml(30): Error: Cannot resolve attribute 'port' for component type net.flexmojos.oss.unitestingsupport.TestApplication.
C:\Users\Uzer\Documents\Projekt\target\test-classes\TestRunner.mxml(30): Error: Cannot resolve attribute 'controlPort' for component type net.flexmojos.oss.unitestingsupport.TestApplication.
How to fix it and make it work with Flexmojos 7.0.1, any ideas?

Blackberry Phonegap load device showing error

I am developing the blackberry phonegap application. I have set all environment required to build the application. I am using command prompt to debug the application when i build the application it build successfully. But while loading the device it causing error as follows.
C:\bbtest>ant blackberry load-device
Buildfile: C:\bbtest\build.xml
blackberry:
load-device:
generate-cod-name:
[echo] Generated name: cordovaExample.cod
clean:
[delete] Deleting directory C:\bbtest\build
package-app:
[mkdir] Created dir: C:\bbtest\build\widget
[copy] Copying 24 files to C:\bbtest\build\widget
[zip] Building zip: C:\bbtest\build\cordovaExample.zip
load-device:
[exec] [INFO] Parsing command line options
[exec] [INFO] Parsing bbwp.properties
[exec] [INFO] Validating application archive
[exec] [INFO] Parsing config.xml
[exec] [INFO] Populating application source
[exec] [INFO] Compiling BlackBerry WebWorks applicatio
n
[exec] [INFO] Starting signing tool
[exec] [INFO] Signing complete
[exec] [INFO] Generating output files
[exec] [INFO] BlackBerry WebWorks application packagin
g complete
[exec] RIM Wireless Handheld Java Loader
[exec] Copyright 2001-2009 Research In Motion Limited
[exec] Connecting to device...debug: HRESULT error during Open: 80040154
[exec] Error: unable to open port
BUILD FAILED
C:\bbtest\build.xml:49: The following error occurred while executing this line:
C:\bbtest\blackberry.xml:53: exec returned: 3
Total time: 53 seconds
C:\bbtest>
Any Idea why this is happing any help would be appreciated.
Its hard to nail down the problem with that information but I suspect you have a problem with "target name" in your xml.
Make sure the load-device is correctly targeted in your blackberry.xml as shown.
<target name="load-device" depends="package-app">
<bbwp code-sign="true" />
<exec executable="${javaloader}" dir="." failonerror="true">
<arg value="-u" />
<arg value="-w${properties.blackberry.sim.password}" />
<arg value="load" />
<arg file="${build.dir}/StandardInstall/${cod.name}.cod" />
</exec>
</target>
Also make sure that your directories are properly set in project.properties.
blackberry.bbwp.dir=C:\\TheBlackBerryWebWorksSDK
blackberry.sim.dir=C:\\TheEclipseBlackBerry\\plugins\\net.rim.ejde.componentpack5.0.0_5.0.0.25\\components\\simulator
blackberry.mds.dir=C:\\TheBlackBerryWebWorksSDK\\mds
I think that you may not have BlackBerry Desktop Manager installed. You can download this from http://uk.blackberry.com/software/desktop/desktop-pc.html
This error is also thrown when using the incorrect deployment command.
In my case I tried to deploy my application to a BB10 device using ant blackberry load-device instead of ant qnx load-device.
Here's a snippet from the documentation:
BlackBerry 10 (QNX) - ant qnx load-device
BlackBerry PlayBook - ant playbook load-device
BlackBerry Smartphone (OS5-7) - ant blackberry load-device
See http://cordova.apache.org/docs/en/2.5.0/guide_getting-started_blackberry_index.md.html

Can't run "preverify.exe" using Ant's <exec> task

I am having trouble getting my Ant script (for BlackBerry build) to run the preverify.exe command & pass the correct parameters to it.
In the command prompt (Windows 7), this works 100% - the parameters as given work properly:
preverify -verbose -classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar -d build\classes\preverified build\classes\preverified build\classes\unverified
I tried to put this into my Ant script using the following target - trying to use the same parameters:
<target name="preverify">
<mkdir dir="${dest.dir}/classes/preverified" />
<exec executable="${jde.home}/bin/preverify">
<arg value="-verbose" />
<arg value="-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar" />
<arg value="-d build\classes\preverified" />
<arg value="build\classes\unverified" />
</exec>
</target>
This does not work. I get the following error:
Illegal option
-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
this classpath was perfectly acceptable from the command line (often java commands accept JAR files as directories, since they are basically ZIP files).
How can I get Ant to send the correct parameters to this command, as in the command line version? There must be something about exec that I'm missing?
Here is the full Ant output from running this target in verbose mode, if it helps:
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
Trying the default build file: build.xml
Buildfile: C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml
Detected Java version: 1.6 in: C:\Java\jdk1.6.0_24\jre
Detected OS: Windows 7
parsing buildfile C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml with URI = file:/C:/development/ant/test_using_javac_jar_preverify_then_rapc/Cobi/build.xml
Project base dir set to: C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi
parsing buildfile jar:file:/C:/development/tools/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml with URI = jar:file:/C:/development/tools/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
Importing file C:\development\ant\common\constants.xml from C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml
Overriding previous definition of reference to ant.projectHelper
parsing buildfile C:\development\ant\common\constants.xml with URI = file:/C:/development/ant/common/constants.xml
parsing buildfile jar:file:/C:/development/tools/bb-ant-tools/bb-ant-tools.jar!/bb-ant-defs.xml with URI = jar:file:/C:/development/tools/bb-ant-tools/bb-ant-tools.jar!/bb-ant-defs.xml from a zip file
Overriding previous definition of reference to ant.projectHelper
[property] Loading C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\project.properties
[property] Loading C:\development\ant\common\jde5.0.properties
[property] Loading C:\development\ant\common\common.properties
[pathconvert] Set property net_rim_api.jar.dos = C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
Build sequence for target(s) `preverify' is [preverify]
Complete build sequence is [preverify, javac, build, sign, clean, ]
preverify:
[mkdir] Skipping C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build\classes\preverified because it already exists.
[exec] Current OS is Windows 7
[exec] Executing 'C:\development\tools\bb-jde\jde5.0\components\bin\preverify' with arguments:
[exec] '-verbose'
[exec] '-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar'
[exec] '-d build\classes\preverified'
[exec] 'build\classes\unverified'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
[exec] preverify: Illegal option -classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
[exec]
[exec] Usage: preverify [options] classnames|dirnames ...
[exec]
[exec] where options include:
[exec] -classpath <directories separated by ';'>
[exec] Directories in which to look for classes
[exec] -d <directory> Directory in which output is written (default is ./output/)
[exec] -cldc1.0 Checks for existence of language features prohibited
[exec] by CLDC 1.0 (native methods, floating point and finalizers)
[exec] -nofinalize No finalizers allowed
[exec] -nonative No native methods allowed
[exec] -nofp No floating point operations allowed
[exec] #<filename> Read command line arguments from a text file
[exec] Command line arguments must all be on a single line
[exec] Directory names must be enclosed in double quotes (")
[exec]
[exec] Result: 1
BUILD SUCCESSFUL
Total time: 1 second
This doesn't look like an ANT issue. The error message is being returned by the preverify command, proving that ANT is executing it...
I don't understand what this command is supposed to be doing, however the usage message gives a hint as to the root cause:
[exec] Usage: preverify [options] classnames|dirnames ...
[exec]
[exec] where options include:
[exec] -classpath <directories separated by ';'>
[exec] Directories in which to look for classes
You haven't specified a list of directories as the "classpath" parameter.... You've supplied a jar file. Is the command able support jar files?
The way you are passing the parameters is incorrect. The space between the -classpath tag, and the JAR name is not allowed.
You must break that line (and the -d below it) onto 2 lines. This works:
<exec executable="${jde.home}/bin/preverify">
<arg value="-verbose" />
<!-- classpath to the RIM api -->
<arg value="-classpath" />
<arg value="C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar" />
<!-- destination folder -->
<arg value="-d" />
<arg value="build\classes\preverified" />
<!-- source folder -->
<arg value="build\classes\unverified" />
</exec>
I solved this problem by including the jdk\bin directory path in environment variable PATH.

Ant build and empty directories

For some reason, when I use scp to move files from my current machine to the server using ant it always ignores empty directories.
<scp todir="ec2-user#xx.x.x.xxx:/var/www/html" keyfile="${basedir}\..\keys\prod_default.pem" trust="true">
<fileset dir="${staging.dir}" />
</scp>
Why is the case?
Full Update verbose log:
D:\BUILD\SCRIPTS>ant -v -f getcom.xml update
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
Buildfile: D:\BUILD\SCRIPTS\getcom.xml
Detected Java version: 1.7 in: C:\Program Files (x86)\Java\jdk1.7.0_02\jre
Detected OS: Windows Server 2008 R2
parsing buildfile D:\BUILD\SCRIPTS\getcom.xml with URI = file:/D:/BUILD/SCRIPTS/getcom.xml
Project base dir set to: D:\BUILD\SCRIPTS
parsing buildfile jar:file:/C:/ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml
with URI = jar:file:/C:/ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
[property] Loading D:\BUILD\SCRIPTS\build.properties
Build sequence for target(s) `update' is [update]
Complete build sequence is [update, upload, cleanup, staging, export, init, ]
update:
[exec] Current OS is Windows Server 2008 R2
[exec] Executing 'C:\\Program Files (x86)\\subversion\\bin\\\svn' with arguments:
[exec] 'update'
[exec] 'D:\BUILD\SCRIPTS\..\_STAGING\GETOM'
[exec] '--username'
[exec] 'uuuu'
[exec] '--password'
[exec] 'uuuu'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
[exec] Updating 'D:\BUILD\_STAGING\GETOM':
[exec] At revision 134.
[scp] Connecting to xx.0.0.100:22
[scp] done.
[scp] Connecting to xx.0.2.100:22
[scp] done.
BUILD SUCCESSFUL
Total time: 8 seconds
Properties:
svn.repoBaseURL="https://uuu#uuuu.uuuu.com"
svn.username="uuuu"
svn.password="uuuu"
svn.bin=C://Program Files (x86)//subversion//bin//
MSBuildPath=C://WINDOWS//Microsoft.NET//Framework//v4.0.30319//MSBuild.exe
lib.path.ant-contrib=C:/ant/lib/ant-contrib-1.0b3.jar
Please note, folder names have been changed.
You'll have to come up with a workaround. The way that Ant implements the scp means that empty directories are always skipped.
The gist of it is that the Scp class does this:
DirectoryScanner scanner = set.getDirectoryScanner(getProject());
Directory root = new Directory(scanner.getBasedir());
String[] files = scanner.getIncludedFiles();
if (files.length != 0) {
...
}
In other words, it only processes the directory if it contains at least one file.
There is a patch for the Scp task code you might consider, but that means a bespoke Ant build.
The two other approaches that come to mind are
make the directories non-empty by populating with placeholder files (which you can delete once deployed)
create the empty directories in a separate step

Resources