Compare commits

..
Author SHA1 Message Date
Ben McIlwainandGitHub 2bc07349a4 Address technical debt and improve safety in domain flows and models (#3065)
* Address technical debt and improve safety in domain flows and models

- Addressed unhandled empty lists and swallowed exceptions in DomainFlowTmchUtils.
- Improved null safety and immutability guarantees in Fee and LaunchPhase.
- Applied defensive copying in FeeTransformResponseExtension.
  Note: This uses the forceEmptyToNull(nullToEmptyImmutableCopy(...))
  pattern. This defensive copy ensures immutability, while forceEmptyToNull
  is required because JAXB will serialize an empty collection as an empty
  XML tag (which violates EPP XML schemas). Setting it to null ensures
  JAXB omits the tag entirely.
- Corrected JAXB property suppression in FeeCheckResponseExtensionItemStdV1.

* Add pr-polisher skill for automated PR pre-flight checks

* Enhance pr-polisher with more GEMINI.md constraints

Added checks for:
- Incorrect @Nullable imports.
- Unstatically imported utility methods (DateTimeUtils/CacheUtils).
- Redundant transaction wrapping (tm().transact -> tm().reTransact).
- Mutable collection instantiations (ArrayList/HashMap).
2026-05-27 21:45:11 +00:00
Juan CelhayandGitHub 00522fb618 Change Kubernetes Services selectors to target "traffic" label (#3054)
* change spec.selector for kubernetes services

* now really change the selector
2026-05-27 18:59:37 +00:00
Ben McIlwainandGitHub ad992beff9 Add java-ast-refactoring skill (#3064)
This adds a Gemini CLI skill that leverages OpenRewrite to perform Abstract Syntax Tree (AST) based refactoring on Java codebases. It is highly preferred over text-based regex or python scripts because it understands Java semantics, correctly updates imports, and preserves formatting. A custom Python script is also included as a fallback for renaming fields and local variables.
2026-05-27 18:33:38 +00:00
Juan CelhayandGitHub ba91141505 Add postdeploy task in CD pipeline to tag deployed image (#3063)
* add variable for pipeline and region

* remove new lines from script

* add postdeploy task to tag images
2026-05-27 16:24:38 +00:00
gbrodmanandGitHub c1ce73db49 Remove old unused GWT dependency (#3056) 2026-05-27 16:24:16 +00:00
Pavlo TkachandGitHub 00ceb6a7df Add Google Vacuum MGMT to schema allowed diff (#3062) 2026-05-27 15:48:31 +00:00
25 changed files with 657 additions and 172 deletions
@@ -0,0 +1,30 @@
---
name: java-ast-refactoring
description: "AST-aware Java refactoring using OpenRewrite. Use when asked to structurally refactor Java code, change class names, change method signatures/overloads, replace builder patterns, modify annotations, or perform cross-file structural replacements. Note: Renaming fields or local variables/parameters is not supported natively via simple YAML recipes in the standard openrewrite modules."
---
# AST-Aware Java Refactoring
This skill uses OpenRewrite to perform Abstract Syntax Tree (AST) based refactoring on Java codebases. This is highly preferred over text-based regex or python scripts because it understands Java semantics, correctly updates imports, and preserves formatting.
## Parameter and Field Renaming (Last Resort)
Because OpenRewrite's YAML recipes do not natively support simple variable or field renaming, a custom script is provided:
```bash
python3 .gemini/skills/java-ast-refactoring/scripts/safe_rename.py <filepath> <old_name> <new_name>
```
**CRITICAL:** Running this python script is a LAST RESORT. It is a regex-based token replacement that ignores strings and comments, but it lacks true AST understanding. ALWAYS prefer using OpenRewrite recipes (`rewrite.yml`) for structural changes like renaming classes, methods, or moving targets, as OpenRewrite correctly handles imports, types, and cross-file references safely.
## Usage
1. Create a `rewrite.yml` recipe file in the workspace root. Refer to `.gemini/skills/java-ast-refactoring/references/rewrite_recipes.md` for syntax.
2. Execute the script:
```bash
./.gemini/skills/java-ast-refactoring/scripts/run_rewrite.sh rewrite.yml
```
3. The script will safely apply the AST transformations and then automatically run `./gradlew spotlessApply` and `google-java-format --replace` on the modified files to automatically fix any Checkstyle line-length and import ordering issues caused by longer/shorter identifiers. Verify the output using `git diff`.
4. **MANDATORY:** Always run `./gradlew build -x test` (or the equivalent compile task) after running OpenRewrite to ensure no compilation errors were introduced.
## Known Limitations & Troubleshooting
* **Static Imports Dropped on Class Rename:** When using `ChangeType` to rename a class, OpenRewrite may sometimes drop static imports for fields/constants belonging to the old class instead of updating them to the new class. If compilation fails due to "cannot find symbol" for a constant after a class rename, manually restore the static import (e.g., `import static com.new.ClassName.CONSTANT;`).
* **Continuous Improvement:** If any new issues or edge cases are found while running the refactoring (e.g., build failures, formatting issues, or missed transformations), proactively update this skill file (`SKILL.md`) and its accompanying scripts (`scripts/run_rewrite.sh`, `scripts/safe_rename.py`) to permanently fix the issue for future use.
@@ -0,0 +1,82 @@
# OpenRewrite Recipe Reference
OpenRewrite uses declarative YAML recipes to perform structural refactorings.
## Recipe Structure
A recipe file must have a `type`, a `name` (which you will activate), and a `recipeList` containing specific core recipes to execute sequentially.
```yaml
type: specs.openrewrite.org/v1beta/recipe
name: com.example.MyRefactoring
recipeList:
- <CoreRecipe>:
<argument1>: <value>
```
## Core Recipes for Common Operations
### 1. Change Method Name
```yaml
- org.openrewrite.java.ChangeMethodName:
methodPattern: java.util.Collections emptyList()
newMethodName: emptyList
```
### 2. Change Method Target to Static
Moves a method call to a new static method target. Useful for replacing custom utility methods with standard ones.
```yaml
- org.openrewrite.java.ChangeMethodTargetToStatic:
methodPattern: google.registry.model.eppinput.EppInputs createDomain(java.lang.String, java.lang.String)
fullyQualifiedTargetTypeName: google.registry.model.domain.DomainCommand.Create
returnType: google.registry.model.domain.DomainCommand.Create.Builder
```
### 3. Change Type (Rename/Move Class)
Updates the class name and automatically updates all imports across the codebase.
*Note: OpenRewrite occasionally drops `import static` references to fields inside the renamed class. Be prepared to manually restore them if a compilation error occurs.*
```yaml
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: org.joda.time.Instant
newFullyQualifiedTypeName: java.time.Instant
```
### 4. Remove Unused Imports
```yaml
- org.openrewrite.java.RemoveUnusedImports
```
### 5. Change Annotation
```yaml
- org.openrewrite.java.ChangeAnnotation:
annotationPattern: @org.junit.Ignore
newAnnotation: @org.junit.jupiter.api.Disabled
```
### 6. Remove Annotation
```yaml
- org.openrewrite.java.RemoveAnnotation:
annotationPattern: @java.lang.SuppressWarnings("unchecked")
```
### 7. Change Method Arguments
Reorders or removes arguments based on a target signature. `newArgumentTemplate` uses 0-based indexing.
```yaml
- org.openrewrite.java.ChangeMethodAccessLevel:
methodPattern: com.google.common.collect.ImmutableList of(..)
newAccessLevel: protected
```
### 8. Add Import
```yaml
- org.openrewrite.java.AddImport:
type: java.util.List
```
## Method Patterns
OpenRewrite uses a specific pointcut expression language for `methodPattern`:
* `[return-type] [fully-qualified-class-name] [method-name]([parameter-types])`
* `*` matches any type.
* `..` matches any number of parameters.
* Example: `java.lang.String split(java.lang.String, int)`
* Example: `* java.util.List add(..)`
+87
View File
@@ -0,0 +1,87 @@
#!/bin/bash
# Copyright 2026 The Nomulus Authors. All Rights Reserved.
#
# 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.
# Wrapper script to dynamically execute OpenRewrite without modifying build.gradle
if [ -z "$1" ]; then
echo "Usage: $0 <path-to-rewrite.yml>"
exit 1
fi
RECIPE_FILE=$(realpath "$1")
if [ ! -f "$RECIPE_FILE" ]; then
echo "Error: Recipe file $RECIPE_FILE not found."
exit 1
fi
# Extract the name of the recipe from the YAML to activate it
RECIPE_NAME=$(grep -oP '(?<=name: ).*' "$RECIPE_FILE" | head -n 1)
if [ -z "$RECIPE_NAME" ]; then
echo "Error: Could not extract 'name:' from $RECIPE_FILE"
exit 1
fi
INIT_SCRIPT="rewrite-init.gradle"
cat << EOF > "$INIT_SCRIPT"
initscript {
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath("org.openrewrite.rewrite:org.openrewrite.rewrite.gradle.plugin:7.33.0")
}
}
rootProject {
apply plugin: org.openrewrite.gradle.RewritePlugin
rewrite {
activeRecipe("$RECIPE_NAME")
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-testing-frameworks:2.14.0")
rewrite("org.openrewrite.recipe:rewrite-migrate-java:2.11.0")
rewrite("org.openrewrite.recipe:rewrite-spring:5.7.0")
}
}
allprojects {
apply plugin: org.openrewrite.gradle.RewritePlugin
}
EOF
# Copy the recipe file to the workspace root temporarily so OpenRewrite finds it
cp "$RECIPE_FILE" ./rewrite.yml
echo "Executing OpenRewrite recipe: $RECIPE_NAME"
./gradlew --init-script "$INIT_SCRIPT" rewriteRun --no-parallel --no-configuration-cache
echo "Running code formatters to fix Checkstyle line-length and import ordering..."
./gradlew spotlessApply
# Automatically handle line-wrapping and formatting for all files modified by OpenRewrite
MODIFIED_JAVA_FILES=$(git diff --name-only --diff-filter=d | grep "\.java$" || true)
if [ -n "$MODIFIED_JAVA_FILES" ]; then
echo "Applying google-java-format to all modified Java files to enforce LineLength..."
echo "$MODIFIED_JAVA_FILES" | xargs -r google-java-format --replace
fi
# Clean up temporary files
rm "$INIT_SCRIPT"
rm ./rewrite.yml
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
# Copyright 2026 The Nomulus Authors. All Rights Reserved.
#
# 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.
import sys
import re
import os
def usage():
print("Usage: python safe_rename.py <filepath> <old_name> <new_name>")
print("Safely renames an identifier in a Java file, ignoring strings and comments.")
sys.exit(1)
def main():
if len(sys.argv) < 4:
usage()
filepath = sys.argv[1]
old_name = sys.argv[2]
new_name = sys.argv[3]
if not os.path.exists(filepath):
print(f"Error: File {filepath} not found.")
sys.exit(1)
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
# Regex to tokenize Java source safely.
token_pattern = re.compile(
r'(?P<string>"(?:\\.|[^"\\])*")|'
r'(?P<char>\'(?:\\.|[^\'\\])*\')|'
r'(?P<line_comment>//.*)|'
r'(?P<block_comment>/\*[\s\S]*?\*/)|'
r'(?P<ident>[a-zA-Z_$][a-zA-Z0-9_$]*)'
)
def replacer(match):
if match.group('ident') == old_name:
return new_name
return match.group(0)
new_content = token_pattern.sub(replacer, content)
if content == new_content:
print(f"No occurrences of '{old_name}' found to rename in {filepath}.")
else:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"Successfully renamed '{old_name}' to '{new_name}' in {filepath}.")
if __name__ == '__main__':
main()
+40
View File
@@ -0,0 +1,40 @@
---
name: pr-polisher
description: Automated pre-flight checklist to polish PRs. Use this before declaring a task or PR complete to automatically verify license headers, commit hygiene, formatting, and codebase mandates.
---
# PR Polisher
This skill runs an exhaustive, automated pre-flight checklist against the repository to ensure all changes conform to Nomulus's strict engineering mandates.
## When to Use
You MUST activate and execute this workflow immediately before you are about to declare a PR, task, or codebase refactor "done" or ready for human review. Do not declare the task complete until this workflow succeeds with 0 errors.
## Workflow Execution Steps
1. **Run the Automated Analysis Script**
Execute the packaged Python diff-checker script. This script automatically checks commit messages, working tree status, `package-lock.json` modifications, copyright years on new files, and a litany of anti-patterns using regex (e.g., fully-qualified names, incorrect clock injections, generic exception catching).
```bash
python3 ./pr-polisher/scripts/check_diff.py
```
2. **Run Formatting Validation**
Always run the project's formatting tools to ensure checkstyle passes.
```bash
./gradlew spotlessCheck
# OR if formatting is needed:
./gradlew spotlessApply && ./gradlew javaIncrementalFormatApply
```
3. **Verify Test Coverage Additions**
Review your diff (`git diff HEAD^`). If you have added any *new* public methods or modified core logic, manually verify that you have added tests to the corresponding `Test.java` file. A code review is not thorough if it only checks for compilation.
4. **Address Errors & Amend**
If any script throws an error, or if formatting changes were applied, you must stage those fixes and amend your commit:
```bash
git add -u
git commit --amend --no-edit
```
Loop back to Step 1 until the `check_diff.py` script returns `0 ERRORS` and the working directory is clean.
+189
View File
@@ -0,0 +1,189 @@
#!/usr/bin/env python3
import subprocess
import re
import sys
import datetime
# Color codes
RED = "\03.3[91m"
YELLOW = "\03.3[93m"
GREEN = "\03.3[92m"
RESET = "\03.3[0m"
errors_found = 0
warnings_found = 0
def log_error(msg):
global errors_found
errors_found += 1
print(f"{RED}[ERROR]{RESET} {msg}")
def log_warning(msg):
global warnings_found
warnings_found += 1
print(f"{YELLOW}[WARNING]{RESET} {msg}")
def log_success(msg):
print(f"{GREEN}[OK]{RESET} {msg}")
def run_cmd(cmd):
return subprocess.check_output(cmd, shell=True, text=True).strip()
def check_commit_message():
print("--- Checking Commit Message ---")
try:
msg = run_cmd("git log -1 --pretty=format:%B")
lines = msg.split('\n')
subject = lines[0]
if len(subject) > 50:
log_error(f"Commit subject exceeds 50 characters ({len(subject)} chars): '{subject}'")
if not subject[0].isupper():
log_error(f"Commit subject must be capitalized: '{subject}'")
if subject[-1] in ['.', '!', '?']:
log_error(f"Commit subject must not end with punctuation: '{subject}'")
else:
log_success("Commit message format looks good.")
except Exception as e:
log_error(f"Failed to check commit message: {e}")
def check_workspace_clean():
print("\n--- Checking Workspace State ---")
status = run_cmd("git status --porcelain")
if status:
log_error("Workspace is not clean. Uncommitted changes found:\n" + status)
else:
log_success("Working directory is clean.")
def check_package_lock():
print("\n--- Checking package-lock.json ---")
diff_files = run_cmd("git diff HEAD^ --name-only").split('\n')
if "console-webapp/package-lock.json" in diff_files:
log_error("console-webapp/package-lock.json is modified in the diff. Unless NPM dependencies were explicitly changed, revert this file using: git checkout console-webapp/package-lock.json")
else:
log_success("console-webapp/package-lock.json is untouched.")
def check_license_headers():
print("\n--- Checking License Headers on New Files ---")
current_year = str(datetime.datetime.now().year)
added_files = run_cmd("git diff HEAD^ --name-status --diff-filter=A").split('\n')
added_java_files = [f.split('\t')[-1] for f in added_files if f.endswith('.java')]
expected_header = f"// Copyright {current_year} The Nomulus Authors. All Rights Reserved."
for f in added_java_files:
try:
with open(f, 'r') as file:
content = file.read()
if expected_header not in content:
log_error(f"Missing or incorrect copyright year in {f}. Expected: {expected_header}")
except FileNotFoundError:
pass
if not added_java_files:
log_success("No new Java files added.")
def check_diff_anti_patterns():
print("\n--- Checking Code Anti-Patterns in Diff ---")
diff = run_cmd("git diff HEAD^ -U0")
current_file = ""
# Regex Patterns
fqn_pattern = re.compile(r'(?<!import\s)(java\.[a-z0-9.]+\.[A-Z][a-zA-Z0-9]+|google\.registry\.[a-z0-9.]+\.[A-Z][a-zA-Z0-9]+)')
visibility_pattern = re.compile(r'/\*\s*package\s*\*/')
utc_pattern = re.compile(r'ZoneId\.of\("UTC"\)')
now_pattern = re.compile(r'(Instant\.now\(\)|OffsetDateTime\.now\(\)|System\.currentTimeMillis\(\))')
catch_generic_pattern = re.compile(r'catch\s*\(\s*(Exception|Throwable)\s+[a-zA-Z0-9_]+\s*\)')
is_equal_optional_pattern = re.compile(r'\.isEqualTo\(Optional\.of\(')
sleep_pattern = re.compile(r'Thread\.sleep\(')
suppress_pattern = re.compile(r'@SuppressWarnings\(')
wrong_nullable_pattern = re.compile(r'import\s+(?!javax\.annotation\.Nullable;)[a-zA-Z0-9_.]+\.Nullable;')
utility_class_pattern = re.compile(r'\b(DateTimeUtils|CacheUtils)\.[a-z]')
redundant_tx_pattern = re.compile(r'tm\(\)\.transact\(\s*\(\)\s*->\s*tm\(\)\.reTransact')
mutable_collection_pattern = re.compile(r'new\s+(ArrayList|HashMap|HashSet)\s*[<()]')
suppress_count = 0
for line in diff.split('\n'):
if line.startswith('+++ b/'):
current_file = line[6:]
suppress_count = 0
continue
if line.startswith('+') and not line.startswith('+++') and current_file.endswith('.java'):
code_line = line[1:]
# FQN Check
fqn_matches = fqn_pattern.findall(code_line)
if fqn_matches:
# Skip if the match is exactly part of an import or package declaration
if not code_line.strip().startswith('import') and not code_line.strip().startswith('package'):
log_warning(f"[{current_file}] Potential Fully-Qualified Name found: {fqn_matches}. Use imports instead.")
# Package visibility
if visibility_pattern.search(code_line):
log_error(f"[{current_file}] Found '/* package */' modifier. Leave modifier blank instead.")
# Time zones
if utc_pattern.search(code_line):
log_error(f"[{current_file}] Found ZoneId.of(\"UTC\"). Use statically imported ZoneOffset.UTC instead.")
# System clocks
if now_pattern.search(code_line):
log_error(f"[{current_file}] Found un-injected clock (Instant.now / System.currentTimeMillis). Inject Clock instead.")
# Catch generic
if catch_generic_pattern.search(code_line):
log_warning(f"[{current_file}] Catching generic Exception/Throwable. Use specific exceptions.")
# Truth Optionals
if is_equal_optional_pattern.search(code_line):
log_warning(f"[{current_file}] Found .isEqualTo(Optional.of(...)). Use Truth's .hasValue(...) instead.")
# Thread.sleep
if sleep_pattern.search(code_line):
log_warning(f"[{current_file}] Found Thread.sleep(). Use Sleeper instead in tests.")
# SuppressWarnings
if suppress_pattern.search(code_line):
suppress_count += 1
if suppress_count > 1:
log_error(f"[{current_file}] Multiple @SuppressWarnings detected. They must be merged (e.g. {{\"unchecked\", \"foo\"}}).")
else:
suppress_count = 0
# Wrong Nullable
if wrong_nullable_pattern.search(code_line):
log_error(f"[{current_file}] Found incorrect Nullable import. Always use javax.annotation.Nullable.")
# Missing static imports for utilities
if utility_class_pattern.search(code_line):
if not code_line.strip().startswith('import'):
log_warning(f"[{current_file}] Found un-statically imported method from DateTimeUtils/CacheUtils. Use static imports.")
# Redundant transaction wrapping
if redundant_tx_pattern.search(code_line):
log_error(f"[{current_file}] Found redundant transaction wrapping (tm().transact(() -> tm().reTransact(...))).")
# Mutable collection instantiation
if mutable_collection_pattern.search(code_line):
log_warning(f"[{current_file}] Found mutable collection instantiation (ArrayList/HashMap/HashSet). Prefer Guava Immutable collections.")
def main():
print("========================================")
print(" NOMULUS PR POLISHER CHECKLIST ")
print("========================================\n")
check_commit_message()
check_workspace_clean()
check_package_lock()
check_license_headers()
check_diff_anti_patterns()
print("\n========================================")
if errors_found == 0 and warnings_found == 0:
print(f"{GREEN}SUCCESS: All checks passed. PR is polished!{RESET}")
else:
print(f"RESULTS: {RED}{errors_found} ERRORS{RESET}, {YELLOW}{warnings_found} WARNINGS{RESET}")
print("Please address the above issues before declaring the PR complete.")
sys.exit(1 if errors_found > 0 else 0)
if __name__ == "__main__":
main()
-123
View File
@@ -628,18 +628,6 @@
}
}
},
"node_modules/@angular/build/node_modules/@types/node": {
"version": "25.7.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/@types/node/-/node-25.7.0.tgz",
"integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"undici-types": "~7.21.0"
}
},
"node_modules/@angular/build/node_modules/@vitejs/plugin-basic-ssl": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz",
@@ -653,24 +641,6 @@
"vite": "^6.0.0 || ^7.0.0"
}
},
"node_modules/@angular/build/node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@angular/build/node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -694,22 +664,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@angular/build/node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@angular/build/node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -743,15 +697,6 @@
"node": ">= 12"
}
},
"node_modules/@angular/build/node_modules/undici-types": {
"version": "7.21.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/undici-types/-/undici-types-7.21.0.tgz",
"integrity": "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/@angular/build/node_modules/vite": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
@@ -971,24 +916,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@angular/cli/node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@angular/cli/node_modules/cli-spinners": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz",
@@ -1092,22 +1019,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@angular/cli/node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@angular/cli/node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -4695,24 +4606,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@schematics/angular/node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@schematics/angular/node_modules/cli-spinners": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz",
@@ -4816,22 +4709,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@schematics/angular/node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@schematics/angular/node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
-4
View File
@@ -165,10 +165,6 @@ dependencies {
implementation deps['com.google.flogger:flogger']
implementation deps['com.google.guava:guava']
implementation deps['com.google.protobuf:protobuf-java']
// Might need to add this back if we re-add nebula-lint
// gradleLint.ignore('unused-dependency') {
implementation deps['com.google.gwt:gwt-user']
// }
implementation deps['com.google.cloud:google-cloud-compute']
implementation deps['com.google.cloud:google-cloud-core']
implementation deps['com.google.cloud:google-cloud-storage']
-5
View File
@@ -162,7 +162,6 @@ com.google.guava:guava:33.4.8-jre=checkstyle
com.google.guava:guava:33.5.0-jre=annotationProcessor,nonprodAnnotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.6.0-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,checkstyle,compileClasspath,deploy_jar,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.gwt:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.http-client:google-http-client-apache-v2:2.1.0=testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-appengine:1.46.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
@@ -174,7 +173,6 @@ com.google.http-client:google-http-client-protobuf:2.1.0=compileClasspath,deploy
com.google.http-client:google-http-client:2.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.j2objc:j2objc-annotations:3.0.0=checkstyle
com.google.j2objc:j2objc-annotations:3.1=annotationProcessor,compileClasspath,deploy_jar,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.jsinterop:jsinterop-annotations:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.monitoring-client:contrib:1.0.7=testCompileClasspath,testRuntimeClasspath
com.google.monitoring-client:metrics:1.0.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.monitoring-client:stackdriver:1.0.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -350,7 +348,6 @@ jakarta.xml.bind:jakarta.xml.bind-api:4.1.0-M1=compileClasspath,nonprodCompileCl
javax.annotation:javax.annotation-api:1.3.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
javax.inject:javax.inject:1=annotationProcessor,compileClasspath,deploy_jar,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
javax.jdo:jdo2-api:2.3-20090302111651=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
javax.validation:validation-api:1.0.0.GA=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
joda-time:joda-time:2.14.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
junit:junit:4.13.2=nonprodCompileClasspath,nonprodRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
net.arnx:nashorn-promise:0.1.1=testRuntimeClasspath
@@ -463,7 +460,6 @@ org.glassfish.jaxb:jaxb-xjc:4.0.8=jaxb
org.glassfish.jaxb:txw2:4.0.6=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.glassfish.jaxb:txw2:4.0.8=jaxb
org.glassfish.jaxb:xsom:4.0.8=jaxb
org.gwtproject:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.hamcrest:hamcrest-core:1.3=nonprodCompileClasspath,nonprodRuntimeClasspath
org.hamcrest:hamcrest-core:3.0=testCompileClasspath,testRuntimeClasspath
org.hamcrest:hamcrest-library:3.0=testCompileClasspath,testRuntimeClasspath
@@ -563,7 +559,6 @@ org.testcontainers:postgresql:1.21.4=compileClasspath,deploy_jar,nonprodCompileC
org.testcontainers:selenium:1.21.4=testCompileClasspath,testRuntimeClasspath
org.testcontainers:testcontainers:1.21.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.threeten:threetenbp:1.7.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.w3c.css:sac:1.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.webjars.npm:viz.js-graphviz-java:2.1.3=testRuntimeClasspath
org.xerial.snappy:snappy-java:1.1.10.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.xmlresolver:xmlresolver:5.2.2=checkstyle
@@ -57,6 +57,9 @@ public final class DomainFlowTmchUtils {
public SignedMark verifySignedMarks(
ImmutableList<AbstractSignedMark> signedMarks, String domainLabel, Instant now)
throws EppException {
if (signedMarks.isEmpty()) {
throw new SignedMarksListEmptyException();
}
if (signedMarks.size() > 1) {
throw new TooManySignedMarksException();
}
@@ -77,21 +80,21 @@ public final class DomainFlowTmchUtils {
public SignedMark verifyEncodedSignedMark(EncodedSignedMark encodedSignedMark, Instant now)
throws EppException {
if (!encodedSignedMark.getEncoding().equals("base64")) {
if (!"base64".equals(encodedSignedMark.getEncoding())) {
throw new Base64RequiredForEncodedSignedMarksException();
}
byte[] signedMarkData;
try {
signedMarkData = encodedSignedMark.getBytes();
} catch (IllegalStateException e) {
throw new SignedMarkEncodingErrorException();
throw new SignedMarkEncodingErrorException(e);
}
SignedMark signedMark;
try {
signedMark = unmarshalEpp(SignedMark.class, signedMarkData);
} catch (EppException e) {
throw new SignedMarkParsingErrorException();
throw new SignedMarkParsingErrorException(e);
}
if (SignedMarkRevocationList.get().isSmdRevoked(signedMark.getId(), now)) {
@@ -101,22 +104,22 @@ public final class DomainFlowTmchUtils {
try {
tmchXmlSignature.verify(signedMarkData);
} catch (CertificateExpiredException e) {
throw new SignedMarkCertificateExpiredException();
throw new SignedMarkCertificateExpiredException(e);
} catch (CertificateNotYetValidException e) {
throw new SignedMarkCertificateNotYetValidException();
throw new SignedMarkCertificateNotYetValidException(e);
} catch (CertificateRevokedException e) {
throw new SignedMarkCertificateRevokedException();
throw new SignedMarkCertificateRevokedException(e);
} catch (CertificateSignatureException e) {
throw new SignedMarkCertificateSignatureException();
throw new SignedMarkCertificateSignatureException(e);
} catch (SignatureException | XMLSignatureException e) {
throw new SignedMarkSignatureException();
throw new SignedMarkSignatureException(e);
} catch (GeneralSecurityException e) {
throw new SignedMarkCertificateInvalidException();
throw new SignedMarkCertificateInvalidException(e);
} catch (IOException
| MarshalException
| SAXException
| ParserConfigurationException e) {
throw new SignedMarkParsingErrorException();
throw new SignedMarkParsingErrorException(e);
}
if (now.isBefore(signedMark.getCreationTime())) {
@@ -181,6 +184,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkCertificateRevokedException() {
super("Signed mark certificate was revoked");
}
public SignedMarkCertificateRevokedException(Throwable cause) {
this();
initCause(cause);
}
}
/** Certificate used in signed mark signature has expired. */
@@ -189,6 +197,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkCertificateNotYetValidException() {
super("Signed mark certificate not yet valid");
}
public SignedMarkCertificateNotYetValidException(Throwable cause) {
this();
initCause(cause);
}
}
/** Certificate used in signed mark signature has expired. */
@@ -196,6 +209,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkCertificateExpiredException() {
super("Signed mark certificate has expired");
}
public SignedMarkCertificateExpiredException(Throwable cause) {
this();
initCause(cause);
}
}
/** Certificate parsing error, or possibly a bad provider or algorithm. */
@@ -203,6 +221,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkCertificateInvalidException() {
super("Signed mark certificate is invalid");
}
public SignedMarkCertificateInvalidException(Throwable cause) {
this();
initCause(cause);
}
}
/** Invalid signature on a signed mark. */
@@ -210,6 +233,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkCertificateSignatureException() {
super("Signed mark certificate not signed by ICANN");
}
public SignedMarkCertificateSignatureException(Throwable cause) {
this();
initCause(cause);
}
}
/** Invalid signature on a signed mark. */
@@ -217,6 +245,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkSignatureException() {
super("Signed mark signature is invalid");
}
public SignedMarkSignatureException(Throwable cause) {
this();
initCause(cause);
}
}
/** Signed marks must be encoded. */
@@ -226,6 +259,13 @@ public final class DomainFlowTmchUtils {
}
}
/** Signed marks list cannot be empty. */
static class SignedMarksListEmptyException extends RequiredParameterMissingException {
public SignedMarksListEmptyException() {
super("Signed marks list cannot be empty");
}
}
/** Only one signed mark is allowed per application. */
static class TooManySignedMarksException extends ParameterValuePolicyErrorException {
public TooManySignedMarksException() {
@@ -245,6 +285,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkParsingErrorException() {
super("Error while parsing encoded signed mark data");
}
public SignedMarkParsingErrorException(Throwable cause) {
this();
initCause(cause);
}
}
/** Signed mark data is improperly encoded. */
@@ -252,6 +297,11 @@ public final class DomainFlowTmchUtils {
public SignedMarkEncodingErrorException() {
super("Signed mark data is improperly encoded");
}
public SignedMarkEncodingErrorException(Throwable cause) {
this();
initCause(cause);
}
}
}
@@ -15,7 +15,6 @@
package google.registry.model.domain.fee;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableSet;
@@ -31,6 +30,13 @@ import java.time.Period;
*/
public class Fee extends BaseFee {
public static final ImmutableSet<String> FEE_EXTENSION_URIS =
ImmutableSet.of(
ServiceExtension.FEE_1_00.getUri(),
ServiceExtension.FEE_0_12.getUri(),
ServiceExtension.FEE_0_11.getUri(),
ServiceExtension.FEE_0_6.getUri());
@Override
public Fee clone() {
return (Fee) super.clone();
@@ -60,21 +66,15 @@ public class Fee extends BaseFee {
private static Fee createWithCustomDescription(
BigDecimal cost, FeeType type, boolean isPremium, String description) {
Fee instance = new Fee();
instance.cost = checkNotNull(cost);
checkArgument(instance.cost.signum() >= 0, "Cost must be a non-negative number");
instance.type = checkNotNull(type);
checkArgumentNotNull(cost, "Cost cannot be null");
checkArgument(cost.signum() >= 0, "Cost must be a non-negative number");
instance.cost = cost;
instance.type = type;
instance.isPremium = isPremium;
instance.description = description;
return instance;
}
public static final ImmutableSet<String> FEE_EXTENSION_URIS =
ImmutableSet.of(
ServiceExtension.FEE_1_00.getUri(),
ServiceExtension.FEE_0_12.getUri(),
ServiceExtension.FEE_0_11.getUri(),
ServiceExtension.FEE_0_6.getUri());
/** Builder for {@link Fee}. */
public static class Builder extends Buildable.Builder<Fee> {
@@ -63,12 +63,12 @@ public class FeeTransformResponseExtension extends ImmutableObject implements Re
}
public Builder setFees(List<Fee> fees) {
getInstance().fees = fees;
getInstance().fees = forceEmptyToNull(nullToEmptyImmutableCopy(fees));
return this;
}
public Builder setCredits(List<Credit> credits) {
getInstance().credits = forceEmptyToNull(credits);
getInstance().credits = forceEmptyToNull(nullToEmptyImmutableCopy(credits));
return this;
}
}
@@ -14,13 +14,12 @@
package google.registry.model.domain.feestdv1;
import static google.registry.util.CollectionUtils.forceEmptyToNull;
import com.google.common.collect.ImmutableList;
import google.registry.model.domain.Period;
import google.registry.model.domain.fee.Fee;
import google.registry.model.domain.fee.FeeCheckResponseExtensionItem;
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.XmlType;
/** The version 1.0 response for a domain check on a single resource. */
@@ -38,6 +37,7 @@ public class FeeCheckResponseExtensionItemStdV1 extends FeeCheckResponseExtensio
* doesn't support "period".
*/
@Override
@XmlTransient
public Period getPeriod() {
return super.getPeriod();
}
@@ -47,6 +47,7 @@ public class FeeCheckResponseExtensionItemStdV1 extends FeeCheckResponseExtensio
* doesn't support "fee".
*/
@Override
@XmlTransient
public ImmutableList<Fee> getFees() {
return super.getFees();
}
@@ -74,7 +75,7 @@ public class FeeCheckResponseExtensionItemStdV1 extends FeeCheckResponseExtensio
@Override
public Builder setFees(ImmutableList<Fee> fees) {
commandBuilder.setFee(forceEmptyToNull(ImmutableList.copyOf(fees)));
commandBuilder.setFee(fees);
return this;
}
@@ -20,6 +20,7 @@ import google.registry.model.ImmutableObject;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlValue;
import java.util.Objects;
import javax.annotation.Nullable;
/**
* The launch phase of the TLD being addressed by this command.
@@ -46,7 +47,7 @@ import java.util.Objects;
* sets it is the one that needs to make sure the domain isn't a trademark and that the fields are
* correct.
*/
public class LaunchPhase extends ImmutableObject {
public final class LaunchPhase extends ImmutableObject {
/**
* The phase during which trademark holders can submit domain registrations with trademark
@@ -70,6 +71,9 @@ public class LaunchPhase extends ImmutableObject {
return instance;
}
/** Private no-arg constructor required for JAXB and to enforce immutability elsewhere. */
private LaunchPhase() {}
@XmlValue String phase;
/**
@@ -79,6 +83,7 @@ public class LaunchPhase extends ImmutableObject {
* <p>This is currently unused, but is retained so that incoming XMLs that include a subphase can
* have it be reflected back.
*/
@Nullable
@XmlAttribute(name = "name")
String subphase;
@@ -0,0 +1,56 @@
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
//
// 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.
package google.registry.flows.domain;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import google.registry.flows.domain.DomainFlowTmchUtils.SignedMarksListEmptyException;
import google.registry.flows.domain.DomainFlowTmchUtils.SignedMarksMustBeEncodedException;
import google.registry.flows.domain.DomainFlowTmchUtils.TooManySignedMarksException;
import google.registry.model.smd.AbstractSignedMark;
import java.time.Instant;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
class DomainFlowTmchUtilsTest {
private final DomainFlowTmchUtils tmchUtils = new DomainFlowTmchUtils(null);
@Test
void test_verifySignedMarks_emptyList() {
assertThrows(
SignedMarksListEmptyException.class,
() -> tmchUtils.verifySignedMarks(ImmutableList.of(), "example", Instant.now()));
}
@Test
void test_verifySignedMarks_tooManyMarks() {
AbstractSignedMark mark1 = Mockito.mock(AbstractSignedMark.class);
AbstractSignedMark mark2 = Mockito.mock(AbstractSignedMark.class);
assertThrows(
TooManySignedMarksException.class,
() ->
tmchUtils.verifySignedMarks(ImmutableList.of(mark1, mark2), "example", Instant.now()));
}
@Test
void test_verifySignedMarks_notEncoded() {
AbstractSignedMark mark1 = Mockito.mock(AbstractSignedMark.class);
assertThrows(
SignedMarksMustBeEncodedException.class,
() -> tmchUtils.verifySignedMarks(ImmutableList.of(mark1), "example", Instant.now()));
}
}
-1
View File
@@ -112,7 +112,6 @@ ext {
'com.google.flogger:flogger:[0.7.4,)',
'com.google.guava:guava-testlib:[33.0.0-jre,)',
'com.google.guava:guava:[33.0.0-jre,)',
'com.google.gwt:gwt-user:[2.9.0,)',
'com.google.http-client:google-http-client-jackson2:[1.39.0,)',
'com.google.http-client:google-http-client:[1.39.0,)',
'com.google.monitoring-client:contrib:[1.0.7,)',
-5
View File
@@ -139,7 +139,6 @@ com.google.guava:guava:33.4.8-jre=checkstyle
com.google.guava:guava:33.5.0-jre=annotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.6.0-jre=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,checkstyle,deploy_jar,runtimeClasspath,testAnnotationProcessor,testRuntimeClasspath
com.google.gwt:gwt-user:2.10.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:2.0.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-appengine:1.46.3=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-gson:2.1.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
@@ -148,7 +147,6 @@ com.google.http-client:google-http-client-protobuf:2.1.0=deploy_jar,runtimeClass
com.google.http-client:google-http-client:2.1.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.j2objc:j2objc-annotations:3.0.0=checkstyle
com.google.j2objc:j2objc-annotations:3.1=annotationProcessor,deploy_jar,runtimeClasspath,testAnnotationProcessor,testRuntimeClasspath
com.google.jsinterop:jsinterop-annotations:2.0.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.monitoring-client:metrics:1.0.7=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.monitoring-client:stackdriver:1.0.7=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-java6:1.36.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
@@ -272,7 +270,6 @@ jakarta.xml.bind:jakarta.xml.bind-api:4.0.4=deploy_jar,runtimeClasspath,testRunt
javax.annotation:javax.annotation-api:1.3.2=deploy_jar,runtimeClasspath,testRuntimeClasspath
javax.inject:javax.inject:1=annotationProcessor,deploy_jar,runtimeClasspath,testAnnotationProcessor,testRuntimeClasspath
javax.jdo:jdo2-api:2.3-20090302111651=deploy_jar,runtimeClasspath,testRuntimeClasspath
javax.validation:validation-api:1.0.0.GA=deploy_jar,runtimeClasspath,testRuntimeClasspath
joda-time:joda-time:2.14.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
junit:junit:4.13.2=testRuntimeClasspath
net.bytebuddy:byte-buddy:1.18.8=deploy_jar,runtimeClasspath,testRuntimeClasspath
@@ -344,7 +341,6 @@ org.freemarker:freemarker:2.3.34=deploy_jar,runtimeClasspath,testRuntimeClasspat
org.glassfish.jaxb:jaxb-core:4.0.6=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.glassfish.jaxb:jaxb-runtime:4.0.6=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.glassfish.jaxb:txw2:4.0.6=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.gwtproject:gwt-user:2.10.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.hamcrest:hamcrest-core:1.3=testRuntimeClasspath
org.hamcrest:hamcrest:2.1=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.hibernate.models:hibernate-models:1.1.1=deploy_jar,runtimeClasspath,testRuntimeClasspath
@@ -397,7 +393,6 @@ org.testcontainers:jdbc:1.21.4=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.testcontainers:postgresql:1.21.4=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.testcontainers:testcontainers:1.21.4=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.threeten:threetenbp:1.7.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.w3c.css:sac:1.3=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.xerial.snappy:snappy-java:1.1.10.4=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.xmlresolver:xmlresolver:5.2.2=checkstyle
org.yaml:snakeyaml:2.4=deploy_jar,runtimeClasspath,testRuntimeClasspath
+1 -1
View File
@@ -78,7 +78,7 @@ metadata:
name: backend
spec:
selector:
service: backend
traffic: backend-all
ports:
- port: 80
targetPort: http
+1 -1
View File
@@ -85,7 +85,7 @@ metadata:
name: console
spec:
selector:
service: console
traffic: console-all
ports:
- port: 80
targetPort: http
+2 -2
View File
@@ -116,7 +116,7 @@ metadata:
name: frontend
spec:
selector:
service: frontend
traffic: frontend-all
ports:
- port: 80
targetPort: http
@@ -137,7 +137,7 @@ spec:
ipFamilies: [IPv4, IPv6]
ipFamilyPolicy: RequireDualStack
selector:
service: frontend
traffic: frontend-all
ports:
- port: 700
targetPort: epp
+1 -1
View File
@@ -85,7 +85,7 @@ metadata:
name: pubapi
spec:
selector:
service: pubapi
traffic: pubapi-all
ports:
- port: 80
targetPort: http
+1 -1
View File
@@ -25,7 +25,7 @@ com.google.api:api-common:2.47.1=compileClasspath,deploy_jar,runtimeClasspath,te
com.google.api:gax-grpc:2.64.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-httpjson:2.64.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax:2.64.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudkms:v1-rev20260506-2.0.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudkms:v1-rev20260514-2.0.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-monitoring:v3-rev20260129-2.0.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-storage:v1-rev20250312-2.0.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auth:google-auth-library-credentials:1.33.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+2 -1
View File
@@ -202,7 +202,8 @@ steps:
--project=${PROJECT_ID} \
--images="nomulus=gcr.io/${PROJECT_ID}/nomulus@${nomulus_digest}" \
--source=. \
--skaffold-file=release/clouddeploy/skaffold.yaml
--skaffold-file=release/clouddeploy/skaffold.yaml \
--deploy-parameters="deployed_image=gcr.io/${PROJECT_ID}/nomulus@${nomulus_digest},base_image=us-docker.pkg.dev/${PROJECT_ID}/gcr.io/nomulus"
# The tarballs and jars to upload to GCS.
artifacts:
objects:
@@ -32,6 +32,20 @@ serialPipeline:
- phaseId: "stable"
profiles: ["crash"]
percentage: 100
postdeploy:
tasks:
- type: container
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:stable
env:
DEPLOYED_IMAGE: ${{ deploy_params['deployed_image'] }}
BASE_IMAGE: ${{ deploy_params['base_image'] }}
TARGET_ID: ${{ target.id }}
command: ["/bin/bash"]
args:
- "-c"
- |
gcloud artifacts docker tags add $DEPLOYED_IMAGE \
${BASE_IMAGE}:live-cd-${TARGET_ID}
analysis:
# 10 minutes.
duration: 600s
@@ -8,3 +8,7 @@ SET default_table_access_method = heap;
SET default_with_oids = false;
^\\restrict
^\\unrestrict
CREATE SCHEMA google_vacuum_mgmt;
CREATE EXTENSION IF NOT EXISTS google_vacuum_mgmt WITH SCHEMA google_vacuum_mgmt;
COMMENT ON EXTENSION google_vacuum_mgmt IS 'extension for assistive operational tooling';
-- \*not\* creating schema, since initdb creates it