Skip to content
Aravind Pai edited this page Aug 10, 2024 · 2 revisions

Why create this action instead of using the server-based or docker-based actions

Actions that use the plantuml online server or the plantuml docker image work well for most usecases where the diagram descriptions are self-contained and the default JVM options are adequate. However, they have a few limitations as described below. While some of them can be resolved with workarounds or alternate means, good UX requires that the tool adapt to the user's work, not force the user to adapt their work to the tool's limitations.

  1. Cannot specify JVM options: For some usecases, JVM options such as -Xmx, -DPLANTUML_LIMIT_SIZE, -DPLANTUML_SECURITY_PROFILE, -Dplantuml.include.path need to be specified while invoking plantuml. See plantuml FAQ, plantuml preprocessing, plantuml security for more information.

  2. Limited or no support for file inclusions: With the online server, the !include directive does not work. With the docker-based server, it could work but requires several configuration steps as detailed in this answer on the plantuml forum.

  3. Using absolute paths is unintuitive and tedious with Github Actions runners: Plantuml's !include directive has a somewhat surprising behaviour that relative paths are resolved against the location of the diagram description file, not the current working directory where plantuml is invoked. To mitigate this—or even for other reasons—the user may want specify an absolute path.

    Github Actions workflows generally checkout files and download artifacts under the runner machine's standard working directory, denoted by the github context property ${{ github.workspace }}. Defining an absolute path using this property in a docker-based workflow leads to surprising behaviour. For example, in case of Linux runners, Github Actions maps the ${{ github.workspace }} to an undocumented /github/workspace volume inside the docker container. As a result, absolute paths defined in the workflow are not visible inside the container causing failures.

(Not) working example

A complete example illustrating the file inclusion problems is available in my other repository dragondive/masadora here.

The directory has the following structure:

dragondive/masadora
├─ .github/workflows/
│  └─  run-docker-based-plantuml.yml
├─ plantuml/
│  ├─  diagram-with-includes.puml
└─ source/
   └─  common-template.iuml
   └─  diagram-data.json

The diagram-with-includes.puml is the main plantuml diagram description file. The user intends to include two files common-template.iuml and diagram-data.json in the process of generating the diagram. The user wants the diagram filename to be example_diagram.png and placed in the diagrams subdirectory of the working directory.

 @startuml output_filename
 !include input_template
 !$data = %load_json(input_data_file)
 !assert %size($data) != 0 : "failed to load data from 'input_data_file'."

 $data.actor1 -> $data.actor2 : $data.message
 $data.actor2 -> $data.actor1 : $data.reply
 @enduml

The user specifies the CLI arguments as below:

java -jar plantuml.jar -Dinput_template=source/common-template.iuml -Dinput_data_file=source/diagram-data.json -Doutput_file=example_diagram -o diagrams/ plantuml/diagram-with-includes.puml

The user is surprised to observe this does not work as expected. Plantuml resolves the relative paths against the plantuml/ directory, not against the working directory. Hence, it does not find the source/common-template.iuml and source/diagram-data.json files. Moreover, the output file (albeit erroneous) is created under plantuml/diagrams/.

To resolve this, the user modifies the CLI arguments to specify absolute paths as below:

java -jar plantuml.jar -Dinput_template=$(pwd)/source/common-template.iuml -Dinput_data_file=$(pwd)/source/diagram-data.json -Doutput_file=example_diagram -o $(pwd)/diagrams/ plantuml/diagram-with-includes.puml

This does work as expected locally, and generates the below diagram.

example_diagram

Now the user writes a Github Actions workflow, replacing $(pwd) with ${{ github.workspace }}. However, due to the undocumented volume mapping described above, this workflow fails to generate the diagram.

Github Actions logs

As Github clears the Actions logs after a certain time period, the logs from the failed run is copied below for future reference:

 Run Timmy/plantuml-action@v1
   with:
     args: -Dinput_template=source/common-template.iuml -Dinput_data_file=source/diagram-data.json -Doutput_file=example_diagram -o diagrams/ plantuml/diagram-with-includes.puml

 /usr/bin/docker run --name b79b19a6c1193a8d41c995ce9a730c6280bf_1df692 --label 84b79b --workdir /github/workspace --rm -e "INPUT_ARGS" -e "INPUT_VERSION" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_REPOSITORY_OWNER_ID" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_REPOSITORY_ID" -e "GITHUB_ACTOR_ID" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKFLOW_REF" -e "GITHUB_WORKFLOW_SHA" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_ENVIRONMENT" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e "ACTIONS_RESULTS_URL" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/masadora/masadora":"/github/workspace" 84b79b:19a6c1193a8d41c995ce9a730c6280bf -Dinput_template=source/common-template.iuml -Dinput_data_file=source/diagram-data.json -Doutput_file=example_diagram -o diagrams/ plantuml/diagram-with-includes.puml
 ... snip ...
 No diagram found
 Run Timmy/plantuml-action@v1
   with:
     args: -Dinput_template=/home/runner/work/masadora/masadora/source/common-template.iuml -Dinput_data_file=/home/runner/work/masadora/masadora/source/diagram-data.json -Doutput_file=example_diagram -o /home/runner/work/masadora/masadora/diagrams/ plantuml/diagram-with-includes.puml

 /usr/bin/docker run --name f899dd6531710bd88a432fbf94234dddd572c8_988564 --label f899dd --workdir /github/workspace --rm -e "INPUT_ARGS" -e "INPUT_VERSION" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_REPOSITORY_OWNER_ID" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_REPOSITORY_ID" -e "GITHUB_ACTOR_ID" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKFLOW_REF" -e "GITHUB_WORKFLOW_SHA" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_ENVIRONMENT" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e "ACTIONS_RESULTS_URL" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/masadora/masadora":"/github/workspace" f899dd:6531710bd88a432fbf94234dddd572c8 -Dinput_template=/home/runner/work/masadora/masadora/source/common-template.iuml -Dinput_data_file=/home/runner/work/masadora/masadora/source/diagram-data.json -Doutput_file=example_diagram -o /home/runner/work/masadora/masadora/diagrams/ plantuml/diagram-with-includes.puml
 ... snip ...
 No diagram found