Skip to content
Closed
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
62 changes: 62 additions & 0 deletions .github/workflows/java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

name: Java checks

on:
push:
branches:
- main
paths:
- "java/**"
- "spec/**"
- ".github/workflows/java.yml"
pull_request:
paths:
- "java/**"
- "spec/**"
- ".github/workflows/java.yml"

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
java-version: ['17', '21', '23', '24']
fail-fast: false

name: Java ${{ matrix.java-version }} Tests
steps:
- uses: actions/checkout@v4

- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'

- name: Setup Bazel
uses: bazelbuild/setup-bazelisk@v3

- name: Run Tests
# Force Bazel to use the local JDK setup by actions/setup-java
run: |
bazel test \
--java_runtime_version=local_jdk \
--tool_java_runtime_version=local_jdk \
--test_output=errors \
//java/com/google/dotprompt:all \
//java/com/google/dotprompt/smoke:SmokeTest
69 changes: 69 additions & 0 deletions .github/workflows/publish_java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

name: Publish Java Package
#
# Requirements for this workflow:
#
# 1. Secrets must be configured in the repository settings:
# - OSSRH_USERNAME: The username for Sonatype OSSRH (Maven Central).
# - OSSRH_TOKEN: The password or token for Sonatype OSSRH.
# - MAVEN_GPG_PRIVATE_KEY: The ASCII-armored GPG private key for signing artifacts.
# - MAVEN_GPG_PASSPHRASE: The passphrase for the GPG private key.
#
# 2. GPG Key Formatting:
# - The private key should be exported using: `gpg --armor --export-secret-keys <ID>`
# - Ensure the key has no empty lines or formatting issues when pasted into GitHub Secrets.
#

on:
release:
types: [created]

jobs:
publish-java:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

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

- name: Setup Bazel
uses: bazelbuild/setup-bazelisk@v3

- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

- name: Publish to Maven Central
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
run: |
./scripts/publish-java.sh \
"${{ steps.import_gpg.outputs.keyring }}" \
"${{ secrets.MAVEN_GPG_PASSPHRASE }}" \
"$MAVEN_USERNAME" \
"$MAVEN_PASSWORD"
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ bazel_dep(name = "platforms", version = "1.0.0")
include("//:go.MODULE.bazel")
include("//:java.MODULE.bazel")
include("//:rust.MODULE.bazel")
include("//:kotlin.MODULE.bazel")
include("//:ts.MODULE.bazel")
260 changes: 203 additions & 57 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions docs/contributing/coding_guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ You are an expert Python developer contributing to the Google Dotprompt project.
- **Language**: Python.
- **Environment Management**: Use `uv` for packaging and environment management.

### Libraries
- **JSON**: Use **Jackson** for JSON parsing and serialization. Avoid Gson.
- **Testing**: Use **Google Truth** (`com.google.truth.Truth`) for assertions. Use JUnit 4/5 for test runners.
- **Utilities**: Use **Guava** for immutable collections and common utilities.
- **Dependency Injection**: Use **Dagger** for dependency injection.

## 2. Typing & Style
- **Type Unions**: Use the pipe operator `|` (PEP 604) for union types (e.g., `int | str`) instead of `typing.Union`. Use `| None` for optional types.
- **Generics**: Use standard collection generics (PEP 585) like `list`, `dict`, `tuple` (lowercase) for type hints instead of `typing.List`, `typing.Dict`.
Expand Down
20 changes: 4 additions & 16 deletions java.MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,19 @@ java_toolchain = use_repo_rule("@rules_java//java:repositories.bzl", "java_toolc

java_toolchain(
name = "jdk",
version = "21",
version = "17",
)

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

# Overriding these versions to prevent duplicate version warnings.
maven.artifact(
name = "guava",
artifact = "com.google.guava:guava:33.4.8-jre",
group = "com.google.guava",
version = "33.4.8-jre",
)
maven.artifact(
name = "truth",
artifact = "com.google.truth:truth:1.4.4",
group = "com.google.truth",
version = "1.4.4",
)
maven.install(
artifacts = [
"junit:junit:4.13.2",
"com.google.truth.extensions:truth-proto-extension:1.4.4",
"com.google.truth:truth:1.4.4",
"com.github.jknack:handlebars:4.4.0",
"com.google.guava:guava:33.4.8-jre",
"com.google.guava:guava:33.5.0-jre",
"com.fasterxml.jackson.core:jackson-databind:2.20.1",
"com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.20.1",
],
lock_file = "//:maven_install.json",
repositories = [
Expand Down
7 changes: 6 additions & 1 deletion java.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ common:java21 --tool_java_language_version=21
common:java21 --java_runtime_version=remotejdk_21
common:java21 --tool_java_runtime_version=remotejdk_21

common --config=java21
common:java24 --java_language_version=24
common:java24 --tool_java_language_version=24
common:java24 --java_runtime_version=remotejdk_24
common:java24 --tool_java_runtime_version=remotejdk_24

common --config=java17

# =============================================================================
# junit_test is incompatible with JDK 18+ -
Expand Down
50 changes: 50 additions & 0 deletions java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Deploying Java Dotprompt

This document describes the process for releasing the `dotprompt` Java library to Maven Central.

## Prerequisites

1. **GPG Keys**: You need a GPG key pair to sign artifacts.
* Export the private key: `gpg --armor --export-secret-keys <ID>`
* Note the passphrase.

2. **Sonatype OSSRH Account**: You need an account on [s01.oss.sonatype.org](https://s01.oss.sonatype.org/) (or the legacy server) with access to the `com.google.dotprompt` group ID.

## GitHub Configuration

Configure the following secrets in the GitHub repository settings:

* `OSSRH_USERNAME`: Your Sonatype username.
* `OSSRH_TOKEN`: Your Sonatype password or user token.
* `MAVEN_GPG_PRIVATE_KEY`: The ASCII-armored GPG private key.
* `MAVEN_GPG_PASSPHRASE`: The passphrase for your GPG key.

## Release Process

The release process is automated via GitHub Actions (`.github/workflows/publish_java.yml`).

1. **Create a Release**:
* Go to the "Releases" section on GitHub.
* Draft a new release.
* Create a new tag (e.g., `v0.1.0`).
* Publish the release.

2. **Automation**:
* The `Publish Java Package` workflow will trigger automatically.
* It sets up the JDK and Bazel environment.
* It imports the GPG key.
* It runs `scripts/publish-java.sh`, which invokes `bazel run //java/com/google/dotprompt:dotprompt_pkg.publish`.

3. **Verification**:
* Check the workflow run logs for success.
* Log in to Sonatype OSSRH to verify the staging repository if auto-release is not enabled, or check Maven Central (after a sync delay) if it is.

## Local Testing (Dry Run)

To verifying the build artifacts locally without publishing:

```bash
bazel build //java/com/google/dotprompt:dotprompt_pkg
```

This ensures the POM and JARs are correctly generated.
87 changes: 87 additions & 0 deletions java/com/google/dotprompt/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,90 @@
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

load("@rules_java//java:defs.bzl", "java_library", "java_test")
load("@rules_jvm_external//:defs.bzl", "java_export")

java_library(
name = "dotprompt",
srcs = [
"Dotprompt.java",
"Helpers.java",
"PromptLoader.java",
],
visibility = ["//visibility:public"],
deps = [
"//java/com/google/dotprompt/models",
"//java/com/google/dotprompt/parser",
"//java/com/google/dotprompt/resolvers",
"//java/com/google/dotprompt/store",
"@maven//:com_fasterxml_jackson_core_jackson_annotations",
"@maven//:com_fasterxml_jackson_core_jackson_core",
"@maven//:com_fasterxml_jackson_core_jackson_databind",
"@maven//:com_fasterxml_jackson_dataformat_jackson_dataformat_yaml",
"@maven//:com_github_jknack_handlebars",
"@maven//:com_google_guava_guava",
],
)

java_export(
name = "dotprompt_pkg",
maven_coordinates = "com.google.dotprompt:dotprompt:0.1.0",
pom_template = "pom_template.xml",
visibility = ["//visibility:public"],
runtime_deps = [":dotprompt"],
)

java_test(
name = "DotpromptTest",
srcs = ["DotpromptTest.java"],
test_class = "com.google.dotprompt.DotpromptTest",
deps = [
":dotprompt",
"//java/com/google/dotprompt/models",
"@maven//:com_google_guava_guava",
"@maven//:com_google_truth_truth",
"@maven//:junit_junit",
],
)

java_test(
name = "SpecTest",
srcs = ["SpecTest.java"],
data = ["//spec"],
test_class = "com.google.dotprompt.SpecTest",
deps = [
":dotprompt",
"//java/com/google/dotprompt/models",
"@maven//:com_fasterxml_jackson_core_jackson_databind",
"@maven//:com_fasterxml_jackson_dataformat_jackson_dataformat_yaml",
"@maven//:com_google_guava_guava",
"@maven//:com_google_truth_truth",
"@maven//:junit_junit",
],
)

java_test(
name = "PromptLoaderTest",
srcs = ["PromptLoaderTest.java"],
test_class = "com.google.dotprompt.PromptLoaderTest",
deps = [
":dotprompt",
"//java/com/google/dotprompt/models",
"@maven//:com_google_truth_truth",
"@maven//:junit_junit",
],
)

java_test(
name = "HelpersTest",
srcs = ["HelpersTest.java"],
test_class = "com.google.dotprompt.HelpersTest",
deps = [
":dotprompt",
"//java/com/google/dotprompt/models",
"@maven//:com_github_jknack_handlebars",
"@maven//:com_google_truth_truth",
"@maven//:junit_junit",
],
)
Loading
Loading