Skip to content
This repository was archived by the owner on Aug 12, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/arch-repo-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Arch Repo Release

on:
push:
tags:
- "release-*"
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: "Existing tag to release (for example: release-2026.08.08.1)"
required: true
type: string

permissions:
contents: write

concurrency:
group: release-${{ github.event.release.tag_name || github.ref_name || github.event.inputs.tag }}
cancel-in-progress: false

jobs:
build-and-release:
runs-on: ubuntu-latest

steps:
- name: Resolve release tag
id: tag
run: |
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
echo "value=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
elif [ "${GITHUB_EVENT_NAME}" = "release" ]; then
echo "value=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
else
echo "value=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
fi

- name: Checkout tag source
uses: actions/checkout@v4
with:
ref: ${{ steps.tag.outputs.value }}
fetch-depth: 0

- name: Validate manual tag exists
if: github.event_name == 'workflow_dispatch'
run: |
git rev-parse --verify "refs/tags/${{ steps.tag.outputs.value }}" >/dev/null

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
cache: "maven"

- name: Build WAR
run: mvn -B -pl structurizr-application -am -Pexclude-playwright -DskipTests package

- name: Generate checksum
run: |
cd structurizr-application/target
sha256sum structurizr-1.0.0.war > structurizr-1.0.0.war.sha256

- name: Create or update release with assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.value }}
name: ${{ steps.tag.outputs.value }}
make_latest: true
append_body: true
body: |
Automated build from tag `${{ steps.tag.outputs.value }}`.
files: |
structurizr-application/target/structurizr-1.0.0.war
structurizr-application/target/structurizr-1.0.0.war.sha256
fail_on_unmatched_files: true
overwrite_files: true
13 changes: 13 additions & 0 deletions META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Manifest-Version: 1.0
Created-By: Maven WAR Plugin 3.4.0
Build-Jdk-Spec: 25
Implementation-Title: structurizr
Implementation-Version: 1.0.0
Main-Class: org.springframework.boot.loader.launch.WarLauncher
Start-Class: com.structurizr.Application
Spring-Boot-Version: 3.5.13
Spring-Boot-Classes: WEB-INF/classes/
Spring-Boot-Lib: WEB-INF/lib/
Spring-Boot-Classpath-Index: WEB-INF/classpath.idx
Spring-Boot-Layers-Index: WEB-INF/layers.idx

65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,67 @@ The two quickest ways to get started with the Structurizr tooling are:

## Documentation

See [docs.structurizr.com](https://docs.structurizr.com) for documentation, getting started guides, tutorials, etc.
See [docs.structurizr.com](https://docs.structurizr.com) for documentation, getting started guides, tutorials, etc.

## Trimble Identity integration (enterprise hosting)

This repository can be configured for enterprise-hosted deployments that require:

- OIDC sign-in for the web UI.
- Token-based API authentication for workspace uploads.
- Admin-key based workspace creation and key-based pushes.

The key properties are:

```properties
structurizr.authentication=oidc

# OIDC web login
structurizr.authentication.oidc.issueruri=https://id.trimble.com
structurizr.authentication.oidc.clientid=<client-id>
structurizr.authentication.oidc.clientsecret=<client-secret-optional>
structurizr.authentication.oidc.scopes=openid,profile,email
structurizr.authentication.oidc.usernameclaim=email

# API upload token validation
structurizr.authentication.api.issueruri=https://id.trimble.com
structurizr.authentication.api.jwkseturi=https://id.trimble.com/.well-known/jwks.json
structurizr.authentication.api.audience=structurizr-upload
structurizr.authentication.api.scopes=structurizr.upload

# Optional migration fallback
structurizr.authentication.api.sharedtoken=
```

When configured, numeric-ID workspace uploads can pass a client-credentials OAuth access token via `-key`, e.g.:

```bash
java -jar structurizr-1.0.0.war push -url https://structurizr-app.example.com/api -id 2 -workspace ./workspace.json -key "$ACCESS_TOKEN" -merge false -archive true
```

For key-based pushes, define a stable workspace key in the workspace DSL:

```dsl
workspace {
properties {
key "dewey"
}
}
```

Then use `push-key` with the server admin key:

```bash
java -jar structurizr-1.0.0.war push-key -url https://structurizr-app.example.com/api -workspace ./workspace.json --adminApiKey "$ADMIN_API_KEY" -merge false -archive true
```

`push-key` reads `properties.key` from the workspace definition and creates or resolves the target workspace automatically. It does not accept `-workspace-key`.

Credential summary:

- `push` uses a workspace API key or configured API bearer token for an existing numeric workspace ID.
- `push-key` uses `--adminApiKey` with the server `ADMIN_API_KEY` because it may create the workspace before pushing to it.

## Build

`.\mvnw.cmd -pl structurizr-application -am -Pexclude-playwright -DskipTests package`
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
<module>structurizr-import</module>
<module>structurizr-inspection</module>
<module>structurizr-application</module>
<module>structurizr-admin-api</module>
<module>structurizr-mcp</module>
</modules>
</project>
25 changes: 25 additions & 0 deletions structurizr-admin-api/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.structurizr</groupId>
<artifactId>structurizr</artifactId>
<version>6.2.0</version>
</parent>

<artifactId>structurizr-admin-api</artifactId>
<packaging>jar</packaging>
<name>structurizr-admin-api</name>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.5.13</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
23 changes: 23 additions & 0 deletions structurizr-application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

<properties>
<app.revision>1.0.0</app.revision>
<app.displayVersion>6.2.0</app.displayVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
</properties>
Expand Down Expand Up @@ -95,6 +96,17 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-client</artifactId>
<version>6.2.0</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
Expand Down Expand Up @@ -151,6 +163,16 @@
<artifactId>spring-security-saml2-service-provider</artifactId>
<version>6.5.9</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>6.5.9</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>6.5.9</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
Expand Down Expand Up @@ -315,6 +337,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>true</excludeDevtools>
<requiresUnpack>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class Application {
register(new ServerCommand());

register(new PushCommand());
register(new PushKeyCommand());
register(new PullCommand());
register(new LockCommand());
register(new UnlockCommand());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public void run(String... args) throws Exception {
option.setRequired(false);
options.addOption(option);

option = new Option("workspace-key", "workspaceKey", true, "Workspace routing key to create or resolve");
option.setRequired(false);
options.addOption(option);

option = new Option("json", "json", false, "Output JSON");
option.setRequired(false);
options.addOption(option);
Expand All @@ -34,13 +38,15 @@ public void run(String... args) throws Exception {

String apiUrl = "";
String apiKey = "";
String workspaceKey = "";
boolean json = false;

try {
CommandLine cmd = commandLineParser.parse(options, args);

apiUrl = cmd.getOptionValue("apiUrl");
apiKey = cmd.getOptionValue("apiKey");
workspaceKey = cmd.getOptionValue("workspaceKey");
json = cmd.hasOption("json");
} catch (ParseException e) {
log.error(e.getMessage());
Expand All @@ -53,7 +59,7 @@ public void run(String... args) throws Exception {
AdminApiClient client = new AdminApiClient(apiUrl, apiKey);
client.setAgent(getAgent());

WorkspaceMetadata workspace = client.createWorkspace();
WorkspaceMetadata workspace = client.createWorkspace(workspaceKey);

if (json) {
ObjectMapper mapper = new ObjectMapper();
Expand Down
Loading
Loading