Migrate from v2 to v3

Removed

Synchronous call

v3 retains the async parameter for v2 compatibility, but setting async: false is no longer allowed and will raise an error.

All these APIs return data containing a taskId. To detect the end of a synchronous action, you need to use the api/tasks/{task-id}. The state information will give you the status of the task.

Table 1. Modified endpoints.

Type

Endpoint

Generated API method name

DELETE

/branches/{branchId}/drafts

resetToBaseline

PUT

/branches/{branchId}/applyChanges

PUT

/branches/{branchId}/baseline

DELETE

/branches/{branchId}/current

unApplyChanges

POST

/projects

createProject

POST

/projects/{project-id-or-name}/archive

PUT

/projects/{project-id-or-name}/reapplyModel

DELETE

/projects/archive/{archive-name}

POST

/projects/restore

DELETE

/versions/{versionId}

Usage example:

Waiting completion of an async task with a shell script.
=!/bin/bash

= Variables
VERSION_ID="your-version-id"
API_BASE_URL="https://your-host:your-port/api"
AUTH_HEADER="Authorization: Bearer your-token"

= 1. Delete the version
echo "Deleting version $VERSION_ID..."
TASK_RESPONSE=$(curl -s -X DELETE "$API_BASE_URL/versions/$VERSION_ID" -H "$AUTH_HEADER" -H "Content-Type: application/json")

= 2. Extract the task ID
TASK_ID=$(echo "$TASK_RESPONSE" | jq -r '.id')

if [ "$TASK_ID" == "null" ] || [ -z "$TASK_ID" ]; then
  echo "Error: Unable to retrieve the task ID."
  exit 1
fi

echo "Task started with ID: $TASK_ID"

= 3. Poll the task status
while true; do
  STATUS_RESPONSE=$(curl -s "$API_BASE_URL/tasks/$TASK_ID" -H "$AUTH_HEADER")
  STATE_ID=$(echo "$STATUS_RESPONSE" | jq -r '.state.id')

  echo "Current status: $STATE_ID"

  if [ "$STATE_ID" == "DONE" ]; then
    echo "Task completed successfully."
    break
  fi

  sleep 2
done
  1. Waiting completion of an async task with a batch script.

@echo off
setlocal enabledelayedexpansion

:: Variables
set "VERSION_ID=your-version-id"
set "API_BASE_URL=https://your-api-url.com"
set "AUTH_HEADER=Authorization: Bearer your-token"

:: 1. Delete the version
echo Deleting version %VERSION_ID%...
for /f "tokens=* delims=" %%i in ('curl -s -X DELETE "%API_BASE_URL%/versions/%VERSION_ID%" -H "%AUTH_HEADER%" -H "Content-Type: application/json"') do set "TASK_RESPONSE=%%i"

:: 2. Extract the task ID
for /f "tokens=* delims=" %%i in ('echo %TASK_RESPONSE% ^| jq -r ".id"') do set "TASK_ID=%%i"

if "%TASK_ID%" == "null" (
echo Error: Unable to retrieve the task ID.
exit /b 1
)

echo Task started with ID: %TASK_ID%

:: 3. Poll the task status
:poll
for /f "tokens=* delims=" %%i in ('curl -s "%API_BASE_URL%/tasks/%TASK_ID%" -H "%AUTH_HEADER%"') do set "STATUS_RESPONSE=%%i"
for /f "tokens=* delims=" %%i in ('echo %STATUS_RESPONSE% ^| jq -r ".state.id"') do set "STATE_ID=%%i"

echo Current state: %STATE_ID%

if "%STATE_ID%" == "DONE" (
echo Task completed successfully.
exit /b 0
)

timeout /t 2 >nul
goto poll
Waiting completion of an async task with the generated API client.
VersionsApi versionsApi = ApiClient.getInstance().getApi().versions()
DtoTask2 task = versionsApi
		.deleteVersion()
		.versionIdPath(versionId)
		.executeAs(r -> r.thenReturn())

TasksApi tasksApi = ApiClient.getInstance().getApi().tasks()
boolean done = false
while (!done) {
	task = tasksApi
			.getTask()
			.taskIdPath(task.id)
			.executeAs { r -> r.thenReturn() }
	if (task.state.id != "SUBMITTED" && task.state.id != "STARTED") {
		done = true
	}
}

Updated

Rename 'artefact(s)' into 'artifact(s)'

The API endpoints and its content are affected. You need to replace every artefact/artefacts by artifact/artifacts in the path or in the content.

curl -X GET "http://localhost:8180/api/artefacts/{artifact-id}" -H "accept: application/vnd.squore.app-v2+json"

Becomes

curl -X GET "http://localhost:8180/api/artifacts/{artifact-id}" -H "accept: application/vnd.squore.app-v3+json"

If you use the generated API Client, you need to switch to the v3 of the DTO (Data Transfer Object).

DtoArtefact2 artefact = ApiClient
		.getInstance()
		.getApi()
		.artefacts()
		.getArtefact()
		.artefactIdPath(artefactId)
		.execute(r -> r.thenReturn())

Becomes

DtoArtifact3 artifact = ApiClient
		.getInstance()
		.getApi()
		.artifacts()
		.getArtifact()
		.artifactIdPath(artifactId)
		.execute(r -> r.thenReturn())
Table 2. Modified paths.

Type

v2

v3

GET

/artefacts/{artefact-id}

/artifacts/{artifact-id}

GET

/artefacts/{artefact-id}/actionItems

/artifacts/{artifact-id}/actionItems

GET

/artefacts/{artefact-id}/chartDefinitions

/artifacts/{artifact-id}/chartDefinitions

GET

/artefacts/{artefact-id}/chartDefinitions/{chart-id}

/artifacts/{artifact-id}/chartDefinitions/{chart-id}

GET

/artefacts/{artefact-id}/charts/{chart-id}

/artifacts/{artifact-id}/charts/{chart-id}

POST

/artefacts/{artefact-id}/charts/{chart-id}/comments

/artifacts/{artifact-id}/charts/{chart-id}/comments

GET

/artefacts/{artefact-id}/children

/artifacts/{artifact-id}/children

POST

/artefacts/{artefact-id}/comments

/artifacts/{artifact-id}/comments

GET

/artefacts/{artefact-id}/context

/artifacts/{artifact-id}/context

GET

/artefacts/{artefact-id}/exportDefinitions

/artifacts/{artifact-id}/exportDefinitions

GET

/artefacts/{artefact-id}/exportDefinitions/{export-id}

/artifacts/{artifact-id}/exportDefinitions/{export-id}

GET

/artefacts/{artefact-id}/exports/{export-id}

/artifacts/{artifact-id}/exports/{export-id}

GET

/artefacts/{artefact-id}/findings

/artifacts/{artifact-id}/findings

GET

/artefacts/{artefact-id}/forms

/artifacts/{artifact-id}/forms

GET

/artefacts/{artefact-id}/forms/{form-id}

/artifacts/{artifact-id}/forms/{form-id}

PUT

/artefacts/{artefact-id}/forms/{form-id}

/artifacts/{artifact-id}/forms/{form-id}

GET

/artefacts/{artefact-id}/highlightDefinitions

/artifacts/{artifact-id}/highlightDefinitions

GET

/artefacts/{artefact-id}/highlightDefinitions/{highlight-id}

/artifacts/{artifact-id}/highlightDefinitions/{highlight-id}

GET

/artefacts/{artefact-id}/highlights/{highlight-id}

/artifacts/{artifact-id}/highlights/{highlight-id}

GET

/artefacts/{artefact-id}/indicators

/artifacts/{artifact-id}/indicators

GET

/artefacts/{artefact-id}/links

/artifacts/{artifact-id}/links

GET

/artefacts/{artefact-id}/logs

/artifacts/{artifact-id}/logs

GET

/artefacts/{artefact-id}/measures

/artifacts/{artifact-id}/measures

GET

/artefacts/{artefact-id}/measures/{measure-id}

/artifacts/{artifact-id}/measures/{measure-id}

GET

/artefacts/{artefact-id}/parent

/artifacts/{artifact-id}/parent

POST

/artefacts/{artefact-id}/query

/artifacts/{artifact-id}/query

GET

/artefacts/{artefact-id}/reportDefinitions

/artifacts/{artifact-id}/reportDefinitions

GET

/artefacts/{artefact-id}/reportDefinitions/{report-id}

/artifacts/{artifact-id}/reportDefinitions/{report-id}

GET

/artefacts/{artefact-id}/reports/{report-id}

/artifacts/{artifact-id}/reports/{report-id}

PUT

/artefacts/{artefact-id}/status

/artifacts/{artifact-id}/status

GET

/artefacts/{artefact-id}/tableDefinitions

/artifacts/{artifact-id}/tableDefinitions

GET

/artefacts/{artefact-id}/tableDefinitions/{table-id}

/artifacts/{artifact-id}/tableDefinitions/{table-id}

GET

/branches/{branchId}/artefacts

/branches/{branchId}/artifacts

GET

/projects/{project-id-or-name}/artefacts

/projects/{project-id-or-name}/artifacts

GET

/versions/{versionId}/artefacts

/versions/{versionId}/artifacts

Handle removal of rules definitions from findings API

A finding API export can be quite large. To avoid duplicated information, we removed rule definitions and make them accessible through a new endpoint.

get /rules
get /rules/{rule-id}

In the examples below ruleId replaces the definition field

A sample finding in the v2 format that includes the definition field
{
  "id": 39,
  "description": "Common realloc mistake: 'name' nulled but not freed upon failure",
  "tool": "CPPCHECK",
  "locations": [
	{
	  ...
	}
  ],
  "definition": {
	"id": "MEMLEAKONREALLOC",
	"name": "Common realloc mistake: 'varname' nulled but not freed upon failure",
	"description": "",
	"categories": [
	  {
		"scale": {
		  "id": "SCALE_SEVERITY",
		  "name": "Severity"
		},
		"level": {
		  "id": "BLOCKER",
		  "name": "Blocking"
		}
	  },
	  {
		"scale": {
		  "id": "SCALE_REMEDIATION",
		  "name": "Remediation Cost"
		},
		"level": {
		  "id": "MEDIUM",
		  "name": "Medium"
		}
	  }
	],
	"families": [
	  {
		"id": "RESOURCE_UTILISATION",
		"name": "Resource Utilization"
	  },
	  {
		"id": "EFFICIENCY",
		"name": "Efficiency"
	  },
	  {
		"id": "MATURITY",
		"name": "Maturity"
	  },
	  {
		"id": "RELIABILITY",
		"name": "Reliability"
	  }
	]
  },
  "relaxStatus": {
	"id": "OPEN_DEFAULT"
  },
  "readOnly": false,
  "manual": false,
  "new": false,
  "suspicious": false
}
A sample finding in the v3 format that includes the ruleId field.
{
  "id": 39,
  "description": "Common realloc mistake: 'name' nulled but not freed upon failure",
  "tool": "CPPCHECK",
  "relaxStatus": {
	"id": "OPEN_DEFAULT"
  },
  "locations": [
	{
	  ...
	}
  ],
  "ruleId": "MEMLEAKONREALLOC",
  "count": 1,
  "emitted": 2,
  "readOnly": false,
  "suspicious": false,
  "new": false,
  "manual": false
}

Update 204 status to 200 with an empty array

This change improves compliance with REST standards and simplifies scripts by removing the need to handle the 204 status code. All GET endpoints that return a list are affected.