Building a GitHub Repository
You can connect and run git repositories on the Signaloid Cloud Compute Engine.
The Signaloid Cloud Compute Engine API currently only supports repositories hosted on GitHub.
When you submit a repository build to the API, the Signaloid Cloud Compute Engine clones your repository (with --recurse-submodules
) and builds your code.
To connect private repositories you need to authorize the Signaloid Cloud Compute Engine to access your GitHub account. You have to do this via the Signaloid Cloud Developer Platform. Refer to documentation on connecting repositories for more details.
This guide uses the Brown-Ham model GitHub repository from the Signaloid public demo repositories as an example. The following code examples show how to connect and build the repository using the Signaloid Cloud Compute Engine API.
The repository Build request communication and schema are different when running repository tasks compared to single-file source code builds.
For building a repository you need to connect the repository first and then provide the repository identifier (RepositoryID
) to the Signaloid Cloud Compute Engine, instead of sending the entire application source with an API request. The repository is connected to your Signaloid Cloud account and any changes you make to the repository object are pulled each time you launch a repository build for this repository.
Prerequisites
To run a repository task, you will need to have the following:
- An API key to access the Signaloid Cloud API. Please refer to the Authentication guide for more details.
- A GitHub repository containing the application source code.
- If the repository is private, authorization of the Signaloid Cloud Compute Enging to access your GitHub repositories.
Connecting a repository to your account
To run a repository task you must first connect the repository to your Signaloid Cloud account. You can connect a GitHub repository using the /repositories
endpoint of the API. Through this endpoint, you can also programmatically list your connected repositories and amend their configurations if needed.
To connect a repository to your account you need to send an HTTP POST
request to the /repositories
endpoint with a repository configuration object.
RepositoryConfig
properties like Core
, Arguments
, DataSources
and TraceVariables
will be set as default configuration to the build entity when created via the API.
The TypeScript type definition below shows the structure of the repository configuration object:
- TypeScript
type DataSource = {
Location: string;
ResourceID: string;
ResourceType: "Gateway" | "Bucket" | "Drive" | "SignaloidCloudStorage";
}
type TraceVariable = {
File: string;
LineNumber: number;
Expression: string;
}
type RepositoryConfig = {
RemoteURL: string;
Commit: string;
Branch: string;
BuildDirectory: string;
Arguments: string;
Core?: string;
DataSources?: DataSource[];
TraceVariables?: TraceVariable[];
};
You can also use the Repositories page on the Signaloid Cloud Developer Platform to connect repositories to your account. Please refer to the documentation on connecting repositories for more details.
The code below shows how to connect a repository to your account using the axios
library. The code shows how to use the BuildDirectory
key. We set the BuildDirectory
to src/v3
to instruct the Signaloid Cloud Compute Engine to use the code src/v3
as the application source code and ignore the rest of the directories. The README in the GitHub repository explains the different versions of the Brown-Ham example.
- TypeScript
- cURL
// API token generated from signaloid.io/settings/api
const apiToken = process.env.SIGNALOID_KEY || "scce_yourSignaloidCloudApiKey";
const baseURL = process.env.SIGNALOID_URL || "https://api.signaloid.io";
// Setup HTTP client
const axios = require("axios");
const signaloidClient = axios.create({
baseURL: baseURL,
});
// Setup request headers
signaloidClient.defaults.headers["Authorization"] = `${apiToken}`;
signaloidClient.defaults.headers["Content-Type"] = "application/json";
const repositoryURL = "https://github.com/signaloid/Signaloid-Demo-Metallurgy-BrownHamModel";
const repositoryConfig = {
RemoteURL: repositoryURL,
Commit: "42e4b5a6f5bc8641317f17d0662b54ae9fc587f9",
Branch: "main",
BuildDirectory: "src/v3",
Arguments: "",
};
console.log(`Connecting ${repositoryURL} to your account via the API...`);
let repositoryID;
let connectRepositoryResponse;
try {
connectRepositoryResponse = await signaloidClient.post("/repositories", repositoryConfig);
console.log("connectRepositoryResponse.status :>> ", connectRepositoryResponse.status);
if (connectRepositoryResponse.status === 201) {
repositoryID = connectRepositoryResponse.data.RepositoryID;
console.log(`...repository successfully connected. Repository ID: ${repositoryID}`);
}
} catch (error) {
console.log("Error :>> ", error);
}
# Branch is empty to get the default branch
connectRepositoryRequestBody='{
"RemoteURL": "https://github.com/signaloid/Signaloid-Demo-Metallurgy-BrownHamModel",
"Commit": "HEAD",
"Branch": "",
"BuildDirectory": "src/v3",
"Arguments": "",
"Core": "cor_b21e4de9927158c1a5b603c2affb8a09"
}'
# The following API connects a Github repository with details specified by githubRepositoryObject.
connectCurlReturn=$(curl -s --request POST --location 'https://api.signaloid.io/repositories' \
--header "Content-Type: application/json" \
--header "Authorization: "$signaloidAPIKey \
--data "$connectRepositoryRequestBody")
# Unique identifier of the connected repository
repositoryID=$(echo $connectCurlReturn | jq -r '.RepositoryID')
if [ ! "$repositoryID" == "null" ]
then
echo "GitHub repository connected with ID: "$repositoryID
else
message=$(echo $connectCurlReturn | jq -r '.Message')
echo "Exiting because GitHub repository connection failed with message: \""$message"\""
exit
fi
The Signaloid Cloud Compute Engine API allows you to connect the same repository multiple times to your account. This allows you to keep different configurations of the same GitHub repository. Each connected repository will have a different repository IDs even though they use the same GitHub repository as the base.
Building the repository
Setting up the build request
To build an already connected GitHub repository, you need to POST
a request to /repositories/{RepositoryID}/builds
.
For this request, all the request body properties are optional. The Core
field is optional, and if you do not specify a value, the Signaloid Cloud Compute Engine will build your repository for the C0-XS+
core.
The repository build request object has the following structure:
- TypeScript
type RepositoryBuildRequest = {
CoreID?: string;
TraceVariables?: TraceVariable[];
DataSources?: DataSource[];
Arguments?: string;
};
The Signaloid Cloud Compute Engine API will default to the repository configuration if you do not specify the optional properties on the build request.
Build request for an uncertainty-tracking (UT) C0 or C0 Pro core
The snippet below shows how to initialise a build request object for a connected GitHub repository. The code snippet explicitly sets the target Signaloid core using the CoreID
field.
- TypeScript
- cURL
// Core ID of the C0-S+ core (Uncertain Type)
const coreID = "cor_b21e4de9927158c1a5b603c2affb8a09";
// Repository ID you got from connecting your repository to SCCE
const repositoryIDFromResponse = repositoryID || "rep_b21e4de9927158c1a5b603c2affb8a09";
// Optional request body for the Uncertain Type (UT) core
const repositoryBuildRequest = {
CoreID: coreID
};
console.log("Submitting the build to the API...");
let buildPostResponse;
try {
buildPostResponse = await signaloidClient.post(`repositories/${repositoryIDFromResponse}/builds`, repositoryBuildRequest);
if (buildPostResponse.data.BuildID) {
console.log(`...build successfully created with ID: ${buildPostResponse.data.BuildID}`);
}
} catch (error) {
console.log("Error:", error);
}
# API token generated from signaloid.io/settings/api
# Core ID of the C0-S+ core
signaloidCoreId="cor_b21e4de9927158c1a5b603c2affb8a09"
# Optional request body. Can submit request without it if you have correctly specified the config on connecting repository step
buildObject='{
"CoreID": "'$signaloidCoreId'"
}'
Build request for a C0 or C0 Pro Reference core
You need to use the TraceVariables
element of the Build object to instruct the Signaloid Cloud Compute Engine about which variables it should trace. Your source code may contain multiple variables with the same name, defined in different scopes of your source code. Because of this, the Signaloid Cloud Compute Engine needs to know the file and line number of the declaration of the variable that you want to trace to be able to uniquely identify it.
The following code snippets show how to use the Signaloid API calls to instruct the Signaloid Cloud Compute Engine to build a repository on the C0-Reference core the source code shown at the top of the page. The TraceVariables
element of the Task object, instructs the Signaloid Cloud Compute Engine to trace variable sigmaCMpa
, in line 95 of file Brown-and-Ham-with-all-parameters-as-distributions.c
as you can see in src/v3/src
of the connected GitHub repository.
- TypeScript
- cURL
// Core ID of the C0-Reference core
const coreID = "cor_9a3efb0094405df5aeb61cf1f29606a0";
// Repository ID you got from connecting your repository to SCCE
const repositoryIDFromResponse = repositoryID || "rep_b21e4de9927158c1a5b603c2affb8a09";
// Optional request body for the Reference core with trace variables
const repositoryBuildRequest = {
CoreID: coreID,
TraceVariables: [{
Expression: "sigmaCMpa",
File: "src/v3/src/Brown-and-Ham-with-all-parameters-as-distributions.c",
LineNumber: 95
}]
};
console.log("Submitting the build to the API...");
let buildPostResponse;
try {
buildPostResponse = await signaloidClient.post(`repositories/${repositoryIDFromResponse}/builds`, repositoryBuildRequest);
if (buildPostResponse.data.BuildID) {
console.log(`...build successfully created with ID: ${buildPostResponse.data.BuildID}`);
}
} catch (error) {
console.log("Error:", error);
}
# Core ID of the C0-Reference core
signaloidCoreId="cor_9a3efb0094405df5aeb61cf1f29606a0"
buildObject='{
"RepositoryID": "'$connectedRepositoryID'",
"CoreID": "'$signaloidCoreId'",
"TraceVariables": [{"Expression":"sigmaCMpa","File":"Brown-and-Ham-with-all-parameters-as-distributions.c","LineNumber":95}]
}'
Submitting the build to the API
- TypeScript
- cURL
As with the single-source application, once you have constructed the build request object, you can submit it to the Signaloid Cloud Compute Engine via a POST
request to the /repositories/{RepositoryID}/builds
endpoint.
// API token generated from signaloid.io/settings/api
const apiToken = process.env.SIGNALOID_KEY || "scce_yourSignaloidCloudApiKey";
// Setup HTTP client
const axios = require("axios");
const signaloidClient = axios.create({
baseURL: process.env.SIGNALOID_URL || "https://api.signaloid.io",
});
// Setup request headers
signaloidClient.defaults.headers["Authorization"] = `${apiToken}`;
signaloidClient.defaults.headers["Content-Type"] = "application/json";
// Build id you got back after submitting build to SCCE API
const buildID = buildIDFromResponse || "bld_yourSignaloidBuildID";
// Optinal request body. Can submit request without it if you have correctly specified the config on build step
const taskRequest = {
Arguments: "",
DataSources: [{
Location:"sd0",
ResourceID:"signaloid-cloud-storage:/usr_20f7632ffac04b658180b23fe13aab56",
ResourceType:"SignaloidCloudStorage"
}]
}
console.log("Submitting the task to the API...");
let taskPostResponse;
try {
taskPostResponse = await signaloidClient.post(`builds/${buildID}/tasks`, taskRequest);
if (taskPostResponse?.data?.TaskID) {
taskID = taskPostResponse.data.TaskID;
console.log(`...task successfully created with ID: ${taskID}`);
await getTaskStatus(taskID);
}
} catch (error) {
console.log("Error creating task:", error);
}
The response from the API follows the following structure.
{
"data": {
"BuildID": "bld_003794881cd24297929f4b7f78f3b59e",
},
}
You can now use the BuildID
to retrieve the status and outputs of the build from the API.
Once you have created the build request object, you can submit it to the API via a POST
request to /repositories/{RepositoryID}/builds
. The code snippet below shows how to submit the build request to the API using curl
.
# API token generated from signaloid.io/settings/api
buildEndpointResponse=$(curl -s --request POST --location "https://api.signaloid.io/repositories/$repositoryID/builds" \
--header "Content-Type: application/json" \
--header "Authorization: $signaloidAPIKey" \
--data "$buildObject")
If the build request is valid, and the API has accepted the request, the buildEndpointResponse
variable will contain information about the build. The code snippet below shows the contents of the buildEndpointResponse
variable after the build has been successfully submitted.
{
"data": {
"BuildID": "bld_003794881cd24297929f4b7f78f3b59e",
},
}
You can use a utility like jq
to get the BuildID
:
# You can use the following to get the field corresponding to `BuildID`
buildID=$(echo $buildEndpointResponse | jq -r '.BuildID')
echo "BuildID: "$buildID
The BuildID
will allow you to retrieve the status and outputs of the task from the API.