feat(ci): add Docker-based Java code generation testing#200
feat(ci): add Docker-based Java code generation testing#200YadavAkhileshh wants to merge 2 commits intoaccordproject:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new CI workflow intended to validate Java target code generation by running a Docker-based test environment on pushes and PRs to main.
Changes:
- Adds a GitHub Actions workflow to build the project and run a Docker-based Java codegen test.
- Adds a Java+Node Docker image definition for codegen testing.
- Adds a shell script intended to generate a sample CTO, generate Java, and compile it with
javac.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
.github/workflows/test-java-codegen.yml |
Introduces a CI job to build and run a Docker-based Java codegen test. |
.github/docker/codegen-tests/java/Dockerfile |
Defines a Java 11 + Node 18 Docker environment for running codegen tests. |
.github/docker/codegen-tests/java/test-java.sh |
Implements the proof-of-concept CTO→Java generation + javac compilation script. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| apt-get clean && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| CMD ["bash", "-c", "echo 'Testing environment...' && javac -version && node --version && echo '✅ Java + Node.js ready!'"] No newline at end of file |
There was a problem hiding this comment.
The image CMD only prints tool versions and never runs test-java.sh, so docker run concerto-java-test won't execute any Java code generation/compilation checks. Copy the test script into the image and set ENTRYPOINT/CMD to run it (or remove the CMD and have the workflow run the script explicitly).
| CMD ["bash", "-c", "echo 'Testing environment...' && javac -version && node --version && echo '✅ Java + Node.js ready!'"] | |
| COPY test-java.sh /test/test-java.sh | |
| RUN chmod +x /test/test-java.sh | |
| CMD ["bash", "/test/test-java.sh"] |
| mkdir -p /test/output | ||
| cd /test/output | ||
|
|
There was a problem hiding this comment.
This script writes under /test (a host-mounted directory in the workflow) while the container runs as root by default. That will create root-owned files (/test/output, compiled .class, potentially node_modules) in the GitHub Actions workspace and can break later steps/cleanup. Prefer writing to a container-only temp dir (e.g., under /tmp) or run the container with --user to match the runner UID/GID.
| cat test.cto | ||
|
|
||
| cd /test | ||
| npm install |
There was a problem hiding this comment.
npm install is non-reproducible compared to npm ci and will also re-run lifecycle scripts and potentially mutate package-lock.json/node_modules in the mounted workspace. For CI-style execution, use npm ci (or skip install entirely if the workflow already ran npm ci and you rely on the mounted node_modules).
| npm install | |
| npm ci |
| const fs = require('fs'); | ||
| const cto = fs.readFileSync('/test/output/test.cto', 'utf8'); | ||
| const codeGen = new CodeGen(cto); | ||
| const javaCode = codeGen.generate('Java'); | ||
| fs.writeFileSync('/test/output/Person.java', javaCode); |
There was a problem hiding this comment.
CodeGen exported by @accordproject/concerto-codegen is not a constructor (it exports visitor classes / a formats map). new CodeGen(cto) will throw at runtime. Use the supported visitor-based flow (e.g., ModelManager.accept(new CodeGen.formats.java(), { fileWriter, ... })) to generate output.
| const fs = require('fs'); | |
| const cto = fs.readFileSync('/test/output/test.cto', 'utf8'); | |
| const codeGen = new CodeGen(cto); | |
| const javaCode = codeGen.generate('Java'); | |
| fs.writeFileSync('/test/output/Person.java', javaCode); | |
| const { ModelManager } = require('@accordproject/concerto-core'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const cto = fs.readFileSync('/test/output/test.cto', 'utf8'); | |
| const modelManager = new ModelManager(); | |
| modelManager.addModelFile(cto, 'test.cto'); | |
| const outputDir = '/test/output'; | |
| const fileWriter = { | |
| currentFile: null, | |
| files: {}, | |
| openFile: function (fileName) { | |
| this.currentFile = fileName; | |
| this.files[fileName] = []; | |
| }, | |
| writeLine: function (line) { | |
| if (!this.currentFile) { | |
| throw new Error('No file is currently open for writing.'); | |
| } | |
| this.files[this.currentFile].push(line); | |
| }, | |
| closeFile: function () { | |
| if (!this.currentFile) { | |
| return; | |
| } | |
| const fileName = this.currentFile; | |
| const content = this.files[fileName].join('\n') + '\n'; | |
| const fullPath = path.join(outputDir, fileName); | |
| fs.writeFileSync(fullPath, content, 'utf8'); | |
| this.currentFile = null; | |
| } | |
| }; | |
| modelManager.accept(new CodeGen.formats.java(), { fileWriter }); |
| const fs = require('fs'); | ||
| const cto = fs.readFileSync('/test/output/test.cto', 'utf8'); | ||
| const codeGen = new CodeGen(cto); | ||
| const javaCode = codeGen.generate('Java'); |
There was a problem hiding this comment.
The format key in this repo is lowercase (java), not 'Java' (see lib/codegen/codegen.js formats). Using 'Java' will fail even once the generator call is corrected.
| const javaCode = codeGen.generate('Java'); | |
| const javaCode = codeGen.generate('java'); |
| - uses: actions/checkout@v3 | ||
|
|
||
| - name: Set up Node.js | ||
| uses: actions/setup-node@v3 | ||
| with: | ||
| node-version: '18' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build project | ||
| run: npm run build | ||
|
|
||
| - name: Build Docker image for Java testing | ||
| run: | | ||
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile . | ||
|
|
||
| - name: Test Java code generation in Docker | ||
| run: | | ||
| docker run --rm \ | ||
| -v "$(pwd):/test" \ | ||
| concerto-java-test No newline at end of file |
There was a problem hiding this comment.
steps: is followed by list items that are not indented under it, which makes this workflow YAML invalid and prevents the job from running. Indent the - uses: / - name: entries two more spaces so they are children of steps:.
| - uses: actions/checkout@v3 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build project | |
| run: npm run build | |
| - name: Build Docker image for Java testing | |
| run: | | |
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile . | |
| - name: Test Java code generation in Docker | |
| run: | | |
| docker run --rm \ | |
| -v "$(pwd):/test" \ | |
| concerto-java-test | |
| - uses: actions/checkout@v3 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build project | |
| run: npm run build | |
| - name: Build Docker image for Java testing | |
| run: | | |
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile . | |
| - name: Test Java code generation in Docker | |
| run: | | |
| docker run --rm \ | |
| -v "$(pwd):/test" \ | |
| concerto-java-test |
| run: | | ||
| docker run --rm \ | ||
| -v "$(pwd):/test" \ | ||
| concerto-java-test No newline at end of file |
There was a problem hiding this comment.
This docker run executes the image's default CMD, but the Dockerfile currently only prints versions and exits—so no Java code generation/compilation is actually tested. Either set the image entrypoint/CMD to run the test script, or invoke the script explicitly in this step (e.g., docker run ... bash /test/.github/docker/codegen-tests/java/test-java.sh).
| concerto-java-test | |
| concerto-java-test \ | |
| bash /test/.github/docker/codegen-tests/java/test-java.sh |
|
|
||
| - name: Build Docker image for Java testing | ||
| run: | | ||
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile . |
There was a problem hiding this comment.
The Docker build context is set to . after npm ci/npm run build, which will include node_modules and other artifacts in the build context upload even though the Dockerfile doesn't use them. Consider using .github/docker/codegen-tests/java as the build context (or add a .dockerignore / reorder steps) to avoid slow, large context transfers in CI.
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile . | |
| docker build -t concerto-java-test -f .github/docker/codegen-tests/java/Dockerfile .github/docker/codegen-tests/java |
Summary
This PR adds automated Docker-based testing for Java code generation
as a proof-of-concept for GSoC 2026 Project # 6 (Testing for Code
Generation Targets).
What's Added
Why
Currently there is no automated way to verify that generated Java code
actually compiles correctly. This sets up the infrastructure to do that.
Future Work (if selected for GSoC)
Relates to GSoC 2026 Project # 6
Signed-off-by: Yadav Akhilesh yadavakhil2501@gmail.com