Skip to content

Commit 73e1e7b

Browse files
bedaHovorkaclaude
andcommitted
Extract jDisco library to separate GitHub repository and consume as Maven dependency
Removed the embedded jDisco module and migrated to consuming jDisco 1.2.0 as an external Maven dependency from GitHub Packages, improving modularity and maintainability. Changes: - Remove jdisco/ subdirectory (59 files) - now maintained at github.com/bedaHovorka/jdisco - Configure Gradle to fetch jDisco from GitHub Packages with mavenLocal() fallback - Update Docker build to use GitHub authentication for package access - Add .env.example for GitHub Packages credentials template - Update CI/CD workflow to use GitHub token for dependency resolution - Remove jDisco-specific Maven build from Docker multi-stage process - Update all documentation to reflect external dependency model GitHub Packages authentication required for builds: - Set GITHUB_ACTOR and GITHUB_TOKEN environment variables - Or configure ~/.gradle/gradle.properties with gpr.user and gpr.key - CI/CD authentication automatic via GITHUB_TOKEN Build system now uses three-tier fallback: 1. mavenLocal() cache (fastest, for local jDisco development) 2. GitHub Packages (requires authentication) 3. Build fails with clear error message 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent a73e166 commit 73e1e7b

59 files changed

Lines changed: 125 additions & 8812 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# GitHub Packages Authentication
2+
# Copy this file to .env and fill in your credentials
3+
# Required for downloading jDisco dependency from GitHub Packages
4+
5+
# Your GitHub username
6+
GITHUB_ACTOR=your-github-username
7+
8+
# Your GitHub Personal Access Token with 'read:packages' scope
9+
# Generate at: https://github.com/settings/tokens
10+
GITHUB_TOKEN=your-personal-access-token
11+
12+
# Note: GitHub Packages requires authentication even for public packages
13+
# See: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry

.github/workflows/gradle-java21.yml

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
permissions:
1111
contents: read
1212
checks: write # For test reporting (future)
13+
packages: read # For GitHub Packages (jDisco dependency)
1314

1415
concurrency:
1516
group: ${{ github.workflow }}-${{ github.ref }}
@@ -35,25 +36,12 @@ jobs:
3536
distribution: 'temurin'
3637
java-version: ${{ env.JAVA_VERSION }}
3738

38-
- name: Cache Maven dependencies (for jDisco)
39+
- name: Cache jDisco from GitHub Packages
40+
id: cache-jdisco
3941
uses: actions/cache@v4
4042
with:
41-
path: ~/.m2/repository
42-
key: ${{ runner.os }}-maven-${{ hashFiles('jdisco/pom.xml') }}
43-
restore-keys: |
44-
${{ runner.os }}-maven-
45-
46-
- name: Build jDisco library (Java 6 compatibility)
47-
working-directory: ./jdisco
48-
run: mvn clean install -q
49-
50-
- name: Verify jDisco installation
51-
run: |
52-
if [ ! -f ~/.m2/repository/dk/ruc/keld/jdisco/1.2.0/jdisco-1.2.0.jar ]; then
53-
echo "ERROR: jDisco artifact not found"
54-
exit 1
55-
fi
56-
echo "✓ jDisco 1.2.0 artifact successfully installed"
43+
path: ~/.m2/repository/dk/ruc/keld/jdisco
44+
key: jdisco-1.2.0
5745

5846
- name: Setup Gradle
5947
uses: gradle/actions/setup-gradle@v4
@@ -68,6 +56,9 @@ jobs:
6856
run: chmod +x gradlew
6957

7058
- name: Build and test interlockSim with Gradle
59+
env:
60+
GITHUB_ACTOR: ${{ github.actor }}
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7162
run: ./gradlew clean build shadowJar --no-daemon --warning-mode=all --stacktrace -x integrationTest
7263

7364
- name: Upload JAR artifact

.github/workflows/sonarqube.yml

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ permissions:
1111
contents: read
1212
checks: write
1313
pull-requests: read # Required for PR analysis
14+
packages: read # Required for GitHub Packages (jDisco dependency)
1415

1516
concurrency:
1617
group: ${{ github.workflow }}-${{ github.ref }}
@@ -40,14 +41,6 @@ jobs:
4041
distribution: 'temurin'
4142
java-version: ${{ env.JAVA_VERSION }}
4243

43-
- name: Cache Maven dependencies (for jDisco)
44-
uses: actions/cache@v4
45-
with:
46-
path: ~/.m2/repository
47-
key: ${{ runner.os }}-maven-${{ hashFiles('jdisco/pom.xml') }}
48-
restore-keys: |
49-
${{ runner.os }}-maven-
50-
5144
- name: Cache SonarQube packages
5245
uses: actions/cache@v4
5346
with:
@@ -56,18 +49,6 @@ jobs:
5649
restore-keys: |
5750
${{ runner.os }}-sonar
5851
59-
- name: Build jDisco library (Java 6 compatibility)
60-
working-directory: ./jdisco
61-
run: mvn clean install -q
62-
63-
- name: Verify jDisco installation
64-
run: |
65-
if [ ! -f ~/.m2/repository/dk/ruc/keld/jdisco/1.2.0/jdisco-1.2.0.jar ]; then
66-
echo "ERROR: jDisco artifact not found"
67-
exit 1
68-
fi
69-
echo "✓ jDisco 1.2.0 artifact successfully installed"
70-
7152
- name: Setup Gradle
7253
uses: gradle/actions/setup-gradle@v4
7354
with:
@@ -78,6 +59,9 @@ jobs:
7859
run: chmod +x gradlew
7960

8061
- name: Build and test with coverage
62+
env:
63+
GITHUB_ACTOR: ${{ github.actor }}
64+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8165
run: ./gradlew clean build test jacocoTestReport --no-daemon --warning-mode=all --stacktrace
8266

8367
- name: Upload JaCoCo coverage report

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ text/*.ps
3939
# Docker artifacts
4040
artifacts/
4141

42+
# Environment variables (contains sensitive credentials)
43+
.env
44+
4245
# Maven artifacts (jDisco)
4346
jdisco/target/
4447
.m2/

CLAUDE.md

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,22 @@ Railway Interlocking Simulator - A BSc thesis project (2006/2007) from Brno Univ
1111

1212
## Build System
1313

14-
This project uses Gradle with Kotlin DSL for building. Java 21 LTS is the minimum required version. The jDisco library module remains at Java 6 for compatibility and uses Maven.
14+
This project uses Gradle with Kotlin DSL for building. Java 21 LTS is the minimum required version.
1515

1616
**Migration Notes**:
1717
- Migrated from Apache Ant + Ivy to Gradle in January 2026
1818
- Migrated from Java 11 to Java 21 LTS in January 2026
1919
- Refactored deprecated Observable/Observer to PropertyChangeSupport
20+
- Extracted jDisco library to separate repository in January 2026
2021

2122
### Dependency Management
2223

23-
Dependencies are managed via Gradle:
24-
- **jDisco 1.2.0** - Discrete event simulation library (from Maven local repository, Java 6)
24+
Dependencies are managed via Gradle with fallback strategy:
25+
- **jDisco 1.2.0** - Discrete event simulation library (external Maven dependency, Java 6 compatible)
26+
- Repository: https://github.com/bedaHovorka/jdisco
27+
- Published to GitHub Packages: `https://maven.pkg.github.com/bedaHovorka/jdisco`
28+
- Fallback order: `mavenLocal()` (cache) → GitHub Packages → build fails
29+
- Requires GitHub authentication for package download (see below)
2530
- **JUnit 5.11.4** - Testing framework (JUnit Jupiter API and Engine)
2631
- **AssertJ 3.27.6** - Fluent assertion library for better test readability
2732
- **Mockito 5.21.0** - Mocking framework
@@ -32,6 +37,22 @@ Gradle automatically downloads dependencies during the build. Configuration file
3237
- `settings.gradle.kts` - Project settings
3338
- `gradle.properties` - Version management and build properties
3439

40+
**GitHub Packages Authentication:**
41+
42+
To download jDisco from GitHub Packages, set these environment variables:
43+
```bash
44+
export GITHUB_ACTOR=your-github-username
45+
export GITHUB_TOKEN=your-personal-access-token
46+
```
47+
48+
Or create `~/.gradle/gradle.properties`:
49+
```properties
50+
gpr.user=your-github-username
51+
gpr.key=your-personal-access-token
52+
```
53+
54+
**Note:** In GitHub Actions CI/CD, authentication is automatic via `GITHUB_TOKEN`.
55+
3556
### Common Build Commands
3657

3758
**Clean and build (includes tests and uber JAR):**
@@ -152,9 +173,17 @@ The project includes Docker support for both the Java application and LaTeX thes
152173

153174
### Common Docker Commands
154175

155-
**Build both services:**
176+
**Build services:**
156177
```bash
157-
docker compose build
178+
# Set GitHub credentials for jDisco download
179+
export GITHUB_ACTOR=your-github-username
180+
export GITHUB_TOKEN=your-personal-access-token
181+
182+
# Build app (jDisco downloaded from GitHub Packages or uses local cache)
183+
docker compose build app
184+
185+
# Build thesis
186+
docker compose build text
158187
```
159188

160189
**Run editor GUI:**
@@ -196,11 +225,14 @@ docker compose build app
196225

197226
**Root Dockerfile (multi-stage build):**
198227
1. **Builder stage** - Uses Eclipse Temurin 21 JDK
199-
- Builds jDisco dependency (Maven install, Java 6 compatibility)
200-
- Resolves dependencies via Gradle (automatic download)
228+
- Accepts GITHUB_ACTOR and GITHUB_TOKEN as build args
229+
- Resolves dependencies via Gradle with fallback strategy:
230+
- First tries mavenLocal() cache (if jDisco was built locally)
231+
- Falls back to GitHub Packages (requires authentication)
201232
- Compiles Java sources (Java 21 target)
202233
- Runs all tests with JUnit 5 (build fails if tests fail)
203234
- Creates uber JAR with all dependencies
235+
- Uses BuildKit cache mounts for ~/.m2, ~/.gradle for faster rebuilds
204236
2. **Runner stage** - Eclipse Temurin 21 JRE and X11 libraries
205237
- Minimal runtime environment
206238
- X11 forwarding for GUI support
@@ -257,10 +289,12 @@ If you encounter `java.awt.AWTError: Can't connect to X11 window server`:
257289

258290
### Artifacts
259291

260-
Both services copy build outputs to `/artifacts` inside the container, which is mounted to `./artifacts/` on the host:
292+
Services copy build outputs to `/artifacts` inside the container, which is mounted to `./artifacts/` on the host:
261293
- `artifacts/app/interlockSim.jar` - Compiled application
262294
- `artifacts/text/bakalarka.pdf` - Compiled thesis
263295

296+
**Note:** jDisco is now consumed as a Maven dependency from GitHub Packages, not built locally in Docker.
297+
264298
## Architecture
265299

266300
### Core Components
@@ -283,7 +317,7 @@ Both services copy build outputs to `/artifacts` inside the container, which is
283317

284318
**Simulation engine:**
285319
- Built on jDisco library (discrete event simulation framework by Keld Helsgaun)
286-
- Standalone Maven module in `jdisco/` (Java 6 compatible)
320+
- External dependency from https://github.com/bedavs/jDisco (Java 6 compatible)
287321
- `sim/` package contains simulation processes (e.g., `ShuntingLoop`)
288322

289323
**GUI:**
@@ -335,10 +369,10 @@ src/
335369
│ └── XMLContextFactoryTest.java
336370
└── resources/cz/vutbr/fit/interlockSim/xml/
337371
└── fixtures/ - Test XML files (10 fixtures)
338-
339-
jdisco/ - Third-party discrete event simulation library (Java 6, separate Maven module)
340372
```
341373

374+
**Note:** The jDisco library is now maintained as a separate project at https://github.com/bedavs/jDisco
375+
342376
## Code Style
343377

344378
Follows `.editorconfig` configuration:
@@ -355,7 +389,7 @@ Follows `.editorconfig` configuration:
355389
2. **Tests must exist before modifications** - Any Java source file being modified MUST be covered by tests first. If tests don't exist, they must be written before making any changes
356390
3. **Minimal changes only** - Make only the specific changes requested, nothing more
357391
4. **No unsolicited modernization** - While the project now uses Java 21, do not update Java idioms to modern features, do not add new language features, do not restructure working code
358-
5. **jDisco preservation** - The jDisco module must remain at Java 6 compatibility and should never be modified
392+
5. **jDisco library** - jDisco is now maintained as a separate project. Do not modify jDisco code; report issues at https://github.com/bedavs/jDisco
359393

360394
This is a working historical codebase from 2007. Stability and preservation are more important than modernization.
361395

@@ -561,13 +595,13 @@ The project uses GitHub Actions for automated build, test, and deployment workfl
561595
**Workflow:** `.github/workflows/gradle-java21.yml`
562596

563597
**Features:**
564-
- Builds jDisco library with Java 6 compatibility
565598
- Compiles main project with Java 21
566599
- Runs all tests with JUnit 5
567600
- Packages application JAR
568601
- Uploads JAR as artifact (90-day retention)
569602
- Smoke test execution
570-
- Dependency caching (Maven and Gradle) for faster builds
603+
- Dependency caching (Gradle) for faster builds
604+
- Requires jDisco 1.2.0 from Maven local repository
571605

572606
**Triggers:**
573607
- Push to `main`, `develop`, `feature/**`, `fix/**` branches
@@ -878,9 +912,9 @@ cat docs/deprecated-api-report.md
878912

879913
### jDisco Library
880914

881-
The jDisco library (Java 6 compatible) has **no deprecated API usage**. It should remain at Java 6 compatibility as designed.
915+
The jDisco library (Java 6 compatible) is now maintained as a separate project at https://github.com/bedavs/jDisco and has **no deprecated Java API usage**. It remains at Java 6 compatibility as designed.
882916

883-
**Note:** This analysis is documentation-only. No code changes have been made. See `docs/deprecated-api-report.md` for detailed findings, migration strategies, and recommendations.
917+
**Note:** This analysis is documentation-only for the interlockSim codebase. See `docs/deprecated-api-report.md` for detailed findings about interlockSim. For jDisco deprecation analysis, see the jDisco repository.
884918

885919
## Future Development Considerations
886920

Dockerfile

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,16 @@
1818
# syntax=docker/dockerfile:1.4
1919

2020
# ============================================
21-
# Stage 1: Reference pre-built jDisco image
22-
# ============================================
23-
# Build jdisco separately: docker compose build jdisco
24-
# This avoids duplicating jdisco/Dockerfile logic here
25-
FROM jdisco:latest AS jdisco-builder
26-
27-
# ============================================
28-
# Stage 2: Build interlockSim with Gradle
21+
# Stage 1: Build interlockSim with Gradle
2922
# ============================================
3023
FROM eclipse-temurin:21-jdk AS builder
3124

32-
WORKDIR /build/interlockSim
25+
# Build arguments for GitHub Packages authentication
26+
# These allow Gradle to download jDisco from GitHub Packages
27+
ARG GITHUB_ACTOR
28+
ARG GITHUB_TOKEN
3329

34-
# Copy jDisco from previous stage (required dependency)
35-
COPY --from=jdisco-builder /root/.m2/repository/ /root/.m2/repository/
30+
WORKDIR /build/interlockSim
3631

3732
# Layer 1: Copy Gradle wrapper files (cached until wrapper version changes)
3833
# These files are checked into git and ensure consistent Gradle version
@@ -48,8 +43,11 @@ COPY build.gradle.kts /build/interlockSim/
4843

4944
# Layer 3: Resolve dependencies with BuildKit cache mount
5045
# Gradle caches: dependencies, build cache, and Gradle distributions
46+
# mavenLocal cache is also mounted for jDisco fallback
5147
RUN --mount=type=cache,target=/root/.gradle/caches \
5248
--mount=type=cache,target=/root/.gradle/wrapper \
49+
--mount=type=cache,target=/root/.m2/repository \
50+
GITHUB_ACTOR=${GITHUB_ACTOR} GITHUB_TOKEN=${GITHUB_TOKEN} \
5351
./gradlew dependencies --no-daemon --warning-mode=summary
5452

5553
# Layer 4: Copy source code
@@ -60,6 +58,8 @@ COPY src/ /build/interlockSim/src/
6058
# Tests run during build (haltOnFailure), creating uber JAR with shadowJar
6159
RUN --mount=type=cache,target=/root/.gradle/caches \
6260
--mount=type=cache,target=/root/.gradle/wrapper \
61+
--mount=type=cache,target=/root/.m2/repository \
62+
GITHUB_ACTOR=${GITHUB_ACTOR} GITHUB_TOKEN=${GITHUB_TOKEN} \
6363
./gradlew clean build shadowJar --no-daemon --warning-mode=summary
6464

6565
# Verify JAR was created
@@ -68,7 +68,7 @@ RUN ls -lh /build/interlockSim/build/libs/interlockSim.jar && \
6868
jar tf /build/interlockSim/build/libs/interlockSim.jar | head -20
6969

7070
# ============================================
71-
# Stage 3: Runtime with JRE and X11 support
71+
# Stage 2: Runtime with JRE and X11 support
7272
# ============================================
7373
FROM eclipse-temurin:21-jre AS runner
7474

0 commit comments

Comments
 (0)