The hackathon at the Acumatica Summit drew close to 100 participants in January 2023. One of the projects that drew the most attention was the new Customization API that was introduced in the 2022 R2 version of Acumatica’s REST API. This feature now allows programmers to control and automate the release of their customization packages on the Acumatica platform. This is accomplished by leveraging 2022 R2 REST API Customization Endpoint.
Some of the benefits of this API is to provide confidence through automated validation and publishing. It helps reduce the repetitive steps that you write in your workflow files. We can leverage GitHub Custom Actions for continuous integration, dependency updates, release management, and task automation.
The REST API for this endpoint is fairly straightforward. Below are the 4 endpoints needed to successfully login, import, validate and publish your Acumatica customization package. The help documentation outlines the details of each endpoint.
REST API
Login
http(s)://<Acumatica ERP Instance URL>/entity/auth/login
{
"name": "{{name}}",
"password": "{{password}}",
"company": "{{company}}",
"branch": "{{branch}}"
}
Import
http(s)://<Acumatica ERP Instance URL>/CustomizationApi/Import
{
"projectLevel": 1,
"isReplaceIfExists": true,
"projectName": "ThetaHackathon",
"projectDescription": "Customization Project for Team Theta",
"projectContentBase64": "UEsDBBQAAAAIAHaHOFaekXSEuWEAAB6BAAALAAAA ..."
}
Check Project Validation
Set the isOnlyValidation flag to true to check if the customization is valid. It’s important to include all customization projects in the projectNames parameter in order to be sure that there are no conflicts with existing customization packages. The response will have a log in the JSON body that will let you know what errors are coming back if the validation failed.
http(s)://<Acumatica ERP Instance URL>/CustomizationApi/publishBegin
{
"isMergeWithExistingPackages": false,
"isOnlyValidation": true,
"isOnlyDbUpdates": false,
"isReplayPreviouslyExecutedScripts": false,
"projectNames": [ "ThetaHackathon" ],
"tenantMode": "Current"
}
Publish Customization
Set the isOnlyValidation flag to false to publish the customization to production
http(s)://<Acumatica ERP Instance URL>/CustomizationApi/publishBegin
{
"isMergeWithExistingPackages": false,
"isOnlyValidation": false,
"isOnlyDbUpdates": false,
"isReplayPreviouslyExecutedScripts": false,
"projectNames": [ "ThetaHackathon" ],
"tenantMode": "Current"
}
To check the status of a validation or publication, use publishEnd endpoint. You may need to check periodically every 30 seconds to see if the isComplete flag is true.
http(s)://<Acumatica ERP Instance URL>/CustomizationApi/publishEnd
In the 2023 R1 version of Acumatica, you can get the project as well by calling getProject.
POST http(s)://<Acumatica ERP Instance URL>/CustomizationApi/getProject
Some of the challenges were to get the customization package in a base64 format. In C#, you would need to get the bytes and use a method to create a base 64 string representation of it.
var textBytes = Encoding.UTF8.GetBytes("Hello world!");
// after: 72 101 108 108 111 32 119 111 114 108 100 33
var base64String = Convert.ToBase64String(textBytes, 6, 6);
// after: d29ybGQh
Summary
Special thanks to my outstanding Team Theta at the 2023 Acumatica Hackathon event in Las Vegas. We were able to leverage the Customization API with Github Actions. The goal being able to schedule deployments of customizations after hours in an automated way. This automation can save developers hours of productivity time and more importantly reduce the number of hours worked in off peak hours to help with development efforts for the client.
Resources:
https://app.pluralsight.com/library/courses/building-custom-github-actions/table-of-contents
https://docs.github.com/en/actions/creating-actions/about-custom-actions
https://docs.github.com/en/actions/learn-github-actions/variables
Source Code and Automation for Acumatica Developers
https://github.com/marketplace/actions/wait-for-http-responses
https://github.com/marketplace/actions/wait-sleep
https://docs.github.com/en/actions/learn-github-actions/expressions