diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 776a8a27b..4f4d3f839 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,6 +35,22 @@ env:
GITHUB_ACTIONS_DEPLOY_TIMEOUT: 60
jobs:
+ pre_commit:
+ runs-on: ubuntu-latest
+ outputs:
+ java_version: ${{ env.JAVA_VERSION }}
+ java_version_supported_by_repo: ${{ env.JAVA_VERSION_SUPPORTED_BY_REPO }}
+ steps:
+ - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - id: changed-files
+ uses: Alfresco/alfresco-build-tools/.github/actions/github-list-changes@v7.0.0
+ with:
+ write-list-to-env: true
+ - uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@v7.0.0
+
veracode_sca:
name: "Veracode - Source Clear Scan (SCA)"
runs-on: ubuntu-latest
@@ -119,6 +135,21 @@ jobs:
name: Veracode Pipeline-Scan Results (Human Readable)
path: readable_output.zip
+ pmd_scan:
+ name: "PMD Scan"
+ runs-on: ubuntu-latest
+ if: >
+ github.event_name == 'pull_request' &&
+ !contains(github.event.head_commit.message, '[skip pmd]') &&
+ !contains(github.event.head_commit.message, '[skip tests]')
+ steps:
+ - uses: actions/checkout@v4
+ - uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v7.0.0
+ - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
+ - uses: Alfresco/ya-pmd-scan@v4.1.0
+ with:
+ classpath-build-command: "mvn -ntp package -DskipTests"
+
build_and_test:
name: "Core & Base Snapshot deployment"
runs-on: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..486dcce60
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,14 @@
+repos:
+ - repo: https://github.com/Yelp/detect-secrets
+ rev: v1.5.0
+ hooks:
+ - id: detect-secrets
+ args: ["--baseline", ".secrets.baseline"]
+ - repo: local
+ hooks:
+ - id: check-format-and-headers
+ name: Check format and headers and fix if necessary
+ entry: ./scripts/check-format-and-headers.sh
+ language: script
+ files: ".*.java"
+ pass_filenames: false
diff --git a/.secrets.baseline b/.secrets.baseline
new file mode 100644
index 000000000..0794f6e92
--- /dev/null
+++ b/.secrets.baseline
@@ -0,0 +1,162 @@
+{
+ "version": "1.5.0",
+ "plugins_used": [
+ {
+ "name": "ArtifactoryDetector"
+ },
+ {
+ "name": "AWSKeyDetector"
+ },
+ {
+ "name": "AzureStorageKeyDetector"
+ },
+ {
+ "name": "Base64HighEntropyString",
+ "limit": 4.5
+ },
+ {
+ "name": "BasicAuthDetector"
+ },
+ {
+ "name": "CloudantDetector"
+ },
+ {
+ "name": "DiscordBotTokenDetector"
+ },
+ {
+ "name": "GitHubTokenDetector"
+ },
+ {
+ "name": "GitLabTokenDetector"
+ },
+ {
+ "name": "HexHighEntropyString",
+ "limit": 3.0
+ },
+ {
+ "name": "IbmCloudIamDetector"
+ },
+ {
+ "name": "IbmCosHmacDetector"
+ },
+ {
+ "name": "IPPublicDetector"
+ },
+ {
+ "name": "JwtTokenDetector"
+ },
+ {
+ "name": "KeywordDetector",
+ "keyword_exclude": ""
+ },
+ {
+ "name": "MailchimpDetector"
+ },
+ {
+ "name": "NpmDetector"
+ },
+ {
+ "name": "OpenAIDetector"
+ },
+ {
+ "name": "PrivateKeyDetector"
+ },
+ {
+ "name": "PypiTokenDetector"
+ },
+ {
+ "name": "SendGridDetector"
+ },
+ {
+ "name": "SlackDetector"
+ },
+ {
+ "name": "SoftlayerDetector"
+ },
+ {
+ "name": "SquareOAuthDetector"
+ },
+ {
+ "name": "StripeDetector"
+ },
+ {
+ "name": "TelegramBotTokenDetector"
+ },
+ {
+ "name": "TwilioKeyDetector"
+ }
+ ],
+ "filters_used": [
+ {
+ "path": "detect_secrets.filters.allowlist.is_line_allowlisted"
+ },
+ {
+ "path": "detect_secrets.filters.common.is_baseline_file",
+ "filename": ".secrets.baseline"
+ },
+ {
+ "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
+ "min_level": 2
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_indirect_reference"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_likely_id_string"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_lock_file"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_potential_uuid"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_sequential_string"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_swagger_file"
+ },
+ {
+ "path": "detect_secrets.filters.heuristic.is_templated_secret"
+ }
+ ],
+ "results": {
+ "deprecated/alfresco-transformer-base/src/main/resources/application.yaml": [
+ {
+ "type": "Secret Keyword",
+ "filename": "deprecated/alfresco-transformer-base/src/main/resources/application.yaml",
+ "hashed_secret": "8c1ab56bc026c89468942df91166c35a277455a7",
+ "is_verified": false,
+ "line_number": 10,
+ "is_secret": false
+ }
+ ],
+ "engines/base/src/main/resources/application.yaml": [
+ {
+ "type": "Secret Keyword",
+ "filename": "engines/base/src/main/resources/application.yaml",
+ "hashed_secret": "8c1ab56bc026c89468942df91166c35a277455a7",
+ "is_verified": false,
+ "line_number": 10,
+ "is_secret": false
+ }
+ ],
+ "engines/libreoffice/src/test/resources/quick.vdx": [
+ {
+ "type": "Hex High Entropy String",
+ "filename": "engines/libreoffice/src/test/resources/quick.vdx",
+ "hashed_secret": "37c332070388a4797ccf1fa64f7029a193ce0371",
+ "is_verified": false,
+ "line_number": 2,
+ "is_secret": false
+ }
+ ]
+ },
+ "generated_at": "2024-09-26T14:01:33Z"
+}
diff --git a/alfresco-formatter.xml b/alfresco-formatter.xml
new file mode 100644
index 000000000..9d6b8943a
--- /dev/null
+++ b/alfresco-formatter.xml
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index a2a44bc25..314d155ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,10 @@
1.78.1
+ 2.43.0
+
+ NO_AUTOMATED_FORMATTING
+
false
@@ -247,6 +251,10 @@
${parent.core.deploy.skip}
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+
@@ -358,6 +366,26 @@
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ ${spotless-plugin.version}
+
+
+
+ ${spotless-include-list}
+
+
+ alfresco-formatter.xml
+
+
+ \#java|\#javax|\#jakarta,\#,\#org.alfresco,java|javax|jakarta,,org.alfresco
+
+
+
+
+
+
diff --git a/scripts/check-format-and-headers.sh b/scripts/check-format-and-headers.sh
new file mode 100755
index 000000000..98554e169
--- /dev/null
+++ b/scripts/check-format-and-headers.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+if [[ -z ${GITHUB_MODIFIED_FILES} ]]
+then
+ modified_files=$(git diff --cached --name-only --diff-filter=ACMR)
+else
+ modified_files=${GITHUB_MODIFIED_FILES}
+fi
+
+include_list=""
+for file in ${modified_files}
+do
+ include_list="${include_list},${file}"
+done
+include_list=${include_list:1}
+
+mvn spotless:apply validate -DlicenseUpdateHeaders=true -Dspotless-include-list="${include_list}" > /dev/null