DocumentationPages ManagerCI/CD deployment

CI/CD deployment

Instead of uploading logic files by hand, you can publish them from your build pipeline, for example in Azure DevOps. The pipeline calls the Logic File Publisher API of Pages Manager, and the file arrives in the first environment as if you had used Upload logic file.

Before you start

You need:

  • An API client and its client ID and secret, to get an access token. See API Clients. The API accepts tokens from your identity service at identity-v2.metaforce.net.
  • The Template Environment ID of the environment you want to publish to. Copy it from the environment settings page. If you leave it out, the file goes to the first active environment of the Standard group.

The API is at api.interactadmin.metaforce.net. All calls need the header Authorization: Bearer <access token>.

Publish a file

POST /api/LogicFilePublisher/publish takes a JSON body:

FieldRequiredDescription
fileNameYesThe name of the logic file, for example tenant/logicfile.mfl.
base64ContentYesThe content of the file, Base64 encoded.
templateEnvironmentIdNoThe environment to publish to. Defaults to the first active environment of the Standard group.
fromTemplateEnvironmentIdNoThe environment the file is developed in. When you set it, Pages Manager checks that the smartforms and workflows attached to the file also exist in the target environment, and refuses the publish if they do not. The file’s workflow settings from that environment are then copied to the target environment.
commentNoThe comment that follows the file through the environments.
userNameNoWho published the file.
computerNameNoWhere it was published from.
fileSizeNoSize in bytes. Calculated from the content when omitted.
fileDateNoDate of the file. The current time is used when omitted.
fileOriginNoWhere the file came from. Defaults to 2, which means API.
waitForDownloadNotrue to wait until a server has downloaded the file. Defaults to false.

The response holds the id and versionId of the file, the environment, the size and dates, the comment, who uploaded it, and a status of Success, Accepted or Failed. When the status is Failed, errorMessage says why.

Wait for the download

With waitForDownload left off, the call returns 200 as soon as the file is uploaded. With waitForDownload set to true, the call waits up to about 17 seconds for a server to report that it has downloaded the new version:

  • 200 with status Success when the download was confirmed in time.
  • 202 with status Accepted when it was not confirmed in time. The Location header points to GET /api/LogicFilePublisher/{fileId}/status?uploadDate={uploadDate}. Call it later: downloadedByServer is true once a server has downloaded the file.

Use waitForDownload only if the next step of your pipeline needs the file to be in place.

Validate a file without publishing

POST /api/LogicFilePublisher/validate takes { "base64Content": "..." } and answers with isValid, a message and some properties of the file. Nothing is stored.

Status codes

CodeMeaning
200Done.
202Accepted. The download is not yet confirmed. Only with waitForDownload.
400The request is not valid: a required field is missing, the Base64 content is not valid, the environment does not exist for your company, or a smartform or workflow is missing in the target environment.
401The token is missing or not accepted.
403The token is accepted, but its company has no license for Pages Manager.
500An error on the server.

Example pipeline

The pipeline below gets a token, reads a logic file, converts it to Base64 and publishes it. Replace the placeholders with your own values and keep the client secret in a secret variable.

variables:
fileName: "/tenant/logicfile.mfl" # Change this to each file in the artifact during deployment
comment: "Published from Azure DevOps pipeline $(Build.BuildNumber)"
userName: "$(Build.RequestedFor)"
computerName: "Azure DevOps"
templateEnvironmentId: "YOUR_TEMPLATE_ENVIRONMENT_ID" # From the environment settings page
clientId: "YOUR_CLIENT_ID"
clientSecret: "YOUR_CLIENT_SECRET" # Keep this in a secret variable
identityUrl: "https://identity-v2.metaforce.net"
apiUrl: "https://api.interactadmin.metaforce.net"

# Define the jobs for the pipeline
jobs:
- job: PublishFile
  displayName: "Publish Logic File to Pages Manager"
  steps:
      - task: PowerShell@2
        name: GetAccessToken
        displayName: 'Get Access Token'
        inputs:
          targetType: 'inline'
          script: |
            $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
            $headers.Add("content-type", "application/x-www-form-urlencoded")

            $body = "grant_type=client_credentials&client_id=$(clientId)&client_secret=$(clientSecret)&audience=api&scope=api.external"

            $response = Invoke-RestMethod '$(identityUrl)/connect/token' -Method 'POST' -Headers $headers -Body $body
            Write-Host "##vso[task.setvariable variable=accessToken;isOutput=true]$($response.access_token)"

      - task: PowerShell@2
        name: GenerateLogicFile
        displayName: 'Generate Logic File'
        inputs:
          targetType: 'inline'
          script: |
            # HERE YOU WILL FETCH OR GENERATE THE LOGIC FILE
            # AND CONVERT IT TO BASE64

            $base64Content = [Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$(Build.SourcesDirectory)/$(fileName)"))

            Write-Host "##vso[task.setvariable variable=base64Content;isOutput=true]$($base64Content)"

      - task: PowerShell@2
        displayName: 'Publish Logic File to Pages Manager'
        inputs:
          targetType: 'inline'
          script: |

            $requestBody = @{
              fileName = "$(fileName)"
              base64Content = "$(GenerateLogicFile.base64Content)"
              comment = "$(comment)"
              userName = "$(userName)"
              computerName = "$(computerName)"
              templateEnvironmentId = "$(templateEnvironmentId)"
            } | ConvertTo-Json

            $headers = @{
              "Content-Type" = "application/json"
              "Authorization" = "Bearer $(GetAccessToken.accessToken)"
            }

            $response = Invoke-RestMethod -Uri "$(apiUrl)/api/LogicFilePublisher/publish" -Method Post -Headers $headers -Body $requestBody
            Write-Host "Published file ID: $($response.id)"

            # Optional - log the full response for troubleshooting
            $response | ConvertTo-Json -Depth 5 | Write-Host

Production Kubernetes Environments

The following Kubernetes clusters are used for Pages production deployments:

  • Centerpoint primary production address
    20.23.221.106

  • Centerpoint secondary production address
    135.236.197.89

These endpoints are typically referenced when deploying backend components or when debugging cluster-level integrations. Some tenants may need to white list these addresses in order to access them from internal services.