diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml
index 70475584de..2f31f6e7c0 100644
--- a/.github/workflows/publish-release.yml
+++ b/.github/workflows/publish-release.yml
@@ -37,31 +37,45 @@ jobs:
echo "Published release ${{ steps.get_release.outputs.tag_name }} as latest"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ backfill:
+ name: Backfill master to develop branch
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check params
+ run: |
+ echo "head.ref = ${{github.event.pull_request.head.ref}}"
+ echo "base.ref = ${{github.event.pull_request.base.ref}}"
+
+ - uses: actions/checkout@v4
+ with:
+ ref: master
+ token: ${{ secrets.ACTIONS_NICHOLAS_PAT }}
- - name: Create backfill PR to develop
+ - name: Create backfill branch
+ run: git checkout -b backfill/master;
+
+ # In order to make a commit, we need to initialize a user.
+ - name: Initialize mandatory git config
run: |
- # Check if a PR already exists
- EXISTING_PR=$(gh pr list --base develop --head master --json number --jq '.[0].number' || echo "")
-
- if [ -n "$EXISTING_PR" ]; then
- echo "PR #${EXISTING_PR} already exists for master -> develop"
- exit 0
- fi
-
- # Create the backfill PR
- gh pr create \
- --base develop \
- --head master \
- --title "Backfill master into develop" \
- --body "This PR backfills changes from master into develop after production deployment.
-
- ## Changes
- This includes all changes that were merged to master.
-
- ## Notes
- - Review for any conflicts
- - Merge after verifying all changes are appropriate for develop branch"
-
- echo "Created backfill PR from master to develop"
+ git config user.name "GitHub actions"
+ git config user.email noreply@github.com
+
+ - name: Push backfill branch
env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.ACTIONS_NICHOLAS_PAT }}
+ run: |
+ git push origin backfill/master
+
+ - name: Create backfill pull request to develop branch
+ uses: thomaseizinger/create-pull-request@1.4.0
+ with:
+ github_token: ${{ secrets.ACTIONS_NICHOLAS_PAT }}
+ head: backfill/master
+ base: develop
+ draft: true
+ title: Backfill ${{ github.event.pull_request.base.ref }} branch to develop branch
+ body: |
+ Hi @${{ github.actor }}!
+
+ This PR was created in response to a trigger of the release workflow here: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}.
+ Following a release, this is a backfill from the main branch to the develop branch.
diff --git a/acceptance-tests/pom.xml b/acceptance-tests/pom.xml
index 681cb59fd5..13edbb302f 100644
--- a/acceptance-tests/pom.xml
+++ b/acceptance-tests/pom.xml
@@ -3,7 +3,7 @@
4.0.0
acceptance-tests
gov.cms.qpp.conversion
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
conversion-tests
jar
diff --git a/commandline/pom.xml b/commandline/pom.xml
index 8da3eba944..fa95be16d5 100644
--- a/commandline/pom.xml
+++ b/commandline/pom.xml
@@ -6,7 +6,7 @@
gov.cms.qpp.conversion
qpp-conversion-tool-parent
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
../pom.xml
diff --git a/commons/pom.xml b/commons/pom.xml
index 11fdf3d7d8..61b1d3e206 100644
--- a/commons/pom.xml
+++ b/commons/pom.xml
@@ -6,7 +6,7 @@
gov.cms.qpp.conversion
qpp-conversion-tool-parent
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
../pom.xml
diff --git a/converter/pom.xml b/converter/pom.xml
index 5854a098dc..a4b53f0a9d 100644
--- a/converter/pom.xml
+++ b/converter/pom.xml
@@ -6,7 +6,7 @@
gov.cms.qpp.conversion
qpp-conversion-tool-parent
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
../pom.xml
@@ -185,7 +185,7 @@
gov.cms.qpp.conversion
commons
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
compile
diff --git a/generate-race-cpcplus/pom.xml b/generate-race-cpcplus/pom.xml
index 7f2a135e26..54be01e9f8 100644
--- a/generate-race-cpcplus/pom.xml
+++ b/generate-race-cpcplus/pom.xml
@@ -6,7 +6,7 @@
gov.cms.qpp.conversion
generateRaceCpcPlus
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
generate-race-cpcplus
jar
diff --git a/generate/pom.xml b/generate/pom.xml
index ebca4f0224..b360c7c103 100644
--- a/generate/pom.xml
+++ b/generate/pom.xml
@@ -5,7 +5,7 @@
qpp-conversion-tool-parent
gov.cms.qpp.conversion
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
../pom.xml
4.0.0
diff --git a/pom.xml b/pom.xml
index 12ce54b7d3..2639017c8f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
gov.cms.qpp.conversion
qpp-conversion-tool-parent
pom
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
QPP Conversion Tool
@@ -469,13 +469,13 @@
ch.qos.logback
logback-classic
- 1.5.13
+ 1.5.25
ch.qos.logback
logback-core
- 1.5.13
+ 1.5.25
diff --git a/qrda3-update-measures/pom.xml b/qrda3-update-measures/pom.xml
index 374c4795f4..2bc2e94ece 100644
--- a/qrda3-update-measures/pom.xml
+++ b/qrda3-update-measures/pom.xml
@@ -4,7 +4,7 @@
gov.cms.qpp.conversion
qpp-update-measures
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
qrda3-update-measures
jar
diff --git a/rest-api/pom.xml b/rest-api/pom.xml
index ee1a285862..a03798f1ac 100644
--- a/rest-api/pom.xml
+++ b/rest-api/pom.xml
@@ -19,7 +19,7 @@
gov.cms.qpp.conversion
qpp-conversion-tool-parent
- 2026.02.17.01-RELEASE
+ 2026.02.27.01-RELEASE
../pom.xml
@@ -226,17 +226,17 @@
org.apache.tomcat.embed
tomcat-embed-core
- 10.1.45
+ 10.1.52
org.apache.tomcat.embed
tomcat-embed-el
- 10.1.45
+ 10.1.52
org.apache.tomcat.embed
tomcat-embed-websocket
- 10.1.45
+ 10.1.52
diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/ExceptionHandlerControllerV1.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/exceptions/GlobalExceptionHandler.java
similarity index 81%
rename from rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/ExceptionHandlerControllerV1.java
rename to rest-api/src/main/java/gov/cms/qpp/conversion/api/exceptions/GlobalExceptionHandler.java
index 314d3decd9..c3099a397b 100644
--- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/ExceptionHandlerControllerV1.java
+++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/exceptions/GlobalExceptionHandler.java
@@ -1,35 +1,31 @@
-package gov.cms.qpp.conversion.api.controllers.v1;
+package gov.cms.qpp.conversion.api.exceptions;
-import gov.cms.qpp.conversion.api.exceptions.InvalidFileTypeException;
-import gov.cms.qpp.conversion.api.exceptions.InvalidPurposeException;
-import gov.cms.qpp.conversion.api.exceptions.NoFileInDatabaseException;
+import com.amazonaws.AmazonServiceException;
import gov.cms.qpp.conversion.api.services.AuditService;
import gov.cms.qpp.conversion.model.error.AllErrors;
import gov.cms.qpp.conversion.model.error.QppValidationException;
import gov.cms.qpp.conversion.model.error.TransformException;
-
-import com.amazonaws.AmazonServiceException;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
+import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.context.request.WebRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
-
-import gov.cms.qpp.conversion.api.exceptions.BadZipException;
+import org.springframework.web.servlet.resource.NoResourceFoundException;
/**
* Modify the controller to send back different responses for exceptions
*/
@ControllerAdvice
-public class ExceptionHandlerControllerV1 extends ResponseEntityExceptionHandler {
- private static final Logger API_LOG = LoggerFactory.getLogger(ExceptionHandlerControllerV1.class);
+public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+ private static final Logger API_LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private AuditService auditService;
@@ -38,7 +34,7 @@ public class ExceptionHandlerControllerV1 extends ResponseEntityExceptionHandler
*
* @param auditService {@link AuditService} facilitates persistence of conversion results
*/
- public ExceptionHandlerControllerV1(final AuditService auditService) {
+ public GlobalExceptionHandler(final AuditService auditService) {
this.auditService = auditService;
}
@@ -52,7 +48,9 @@ public ExceptionHandlerControllerV1(final AuditService auditService) {
@ExceptionHandler(TransformException.class)
@ResponseBody
ResponseEntity handleTransformException(TransformException exception) {
- API_LOG.error("Transform exception occurred", exception);
+ API_LOG.info("Transform failed validation (422): {}", exception.getMessage());
+ API_LOG.debug("TransformException details", exception);
+
auditService.failConversion(exception.getConversionReport());
return cope(exception);
}
@@ -67,11 +65,32 @@ ResponseEntity handleTransformException(TransformException exception)
@ExceptionHandler(QppValidationException.class)
@ResponseBody
ResponseEntity handleQppValidationException(QppValidationException exception) {
- API_LOG.error("Validation exception occurred", exception);
+ API_LOG.info("Submission validation failed (422): {}", exception.getMessage());
+ API_LOG.debug("QppValidationException details", exception);
+
auditService.failValidation(exception.getConversionReport());
return cope(exception);
}
+ /**
+ * Handles {@link NoResourceFoundException} for requests to non-existent paths/resources.
+ * Returns a clean 404 and logs at DEBUG/TRACE to avoid ERROR-level noise.
+ */
+ @Override
+ protected ResponseEntity