diff --git a/umbraco-cloud/SUMMARY.md b/umbraco-cloud/SUMMARY.md index e19a8d5c9d5..cf06265c6b2 100644 --- a/umbraco-cloud/SUMMARY.md +++ b/umbraco-cloud/SUMMARY.md @@ -47,9 +47,15 @@ * [Management API Security](set-up/project-settings/management-api-security.md) * [Umbraco CI/CD Flow](set-up/project-settings/umbraco-cicd/README.md) * [Cloud API For CI/CD Flow](set-up/project-settings/umbraco-cicd/UmbracoCloudApi.md) + * [Cloud API For CI/CD Flow V1](set-up/project-settings/umbraco-cicd/v1-umbraco-cloud-api.md) * [Configuring a CI/CD pipeline](set-up/project-settings/umbraco-cicd/samplecicdpipeline/README.md) * [Azure DevOps](set-up/project-settings/umbraco-cicd/samplecicdpipeline/azure-devops.md) * [GitHub Actions](set-up/project-settings/umbraco-cicd/samplecicdpipeline/github-actions.md) + * [Advanced Setup: Deploy to multiple targets](set-up/project-settings/umbraco-cicd/samplecicdpipeline/advanced-multiple-targets.md) + * [Migrate from V1 to V2](set-up/project-settings/umbraco-cicd/samplecicdpipeline/migrate.md) + * [Deployment Artifact best practice](set-up/project-settings/umbraco-cicd/samplecicdpipeline/artifact-best-practice.md) + * [Azure DevOps V1](set-up/project-settings/umbraco-cicd/samplecicdpipeline/v1-azure-devops.md) + * [GitHub Actions V1](set-up/project-settings/umbraco-cicd/samplecicdpipeline/v1-github-actions.md) * [Troubleshooting](set-up/project-settings/umbraco-cicd/Troubleshooting.md) * [Known Limitations and Considerations](set-up/project-settings/umbraco-cicd/KnownLimitationsAndConsiderations.md) * [External Services](set-up/project-settings/external-services.md) diff --git a/umbraco-cloud/set-up/images/Advanced-Section.png b/umbraco-cloud/set-up/images/Advanced-Section.png index 0803edbdc0b..a5beebf168b 100644 Binary files a/umbraco-cloud/set-up/images/Advanced-Section.png and b/umbraco-cloud/set-up/images/Advanced-Section.png differ diff --git a/umbraco-cloud/set-up/images/cicd-target-environments.webp b/umbraco-cloud/set-up/images/cicd-target-environments.webp new file mode 100644 index 00000000000..2f72a0b0adc Binary files /dev/null and b/umbraco-cloud/set-up/images/cicd-target-environments.webp differ diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/KnownLimitationsAndConsiderations.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/KnownLimitationsAndConsiderations.md index dde312f5f30..3ed1e1fbc00 100644 --- a/umbraco-cloud/set-up/project-settings/umbraco-cicd/KnownLimitationsAndConsiderations.md +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/KnownLimitationsAndConsiderations.md @@ -2,10 +2,6 @@ As we continue to gather insights from our users, there are some known limitations and considerations to be aware of. -{% hint style="info" %} -Attaching a CI/CD pipeline to a flexible environment is currently not possible. The CI/CD workflow must go through the mainline deployment workflow. -{% endhint %} - ## Potential Limitations and Considerations **Format Restrictions** diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/UmbracoCloudApi.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/UmbracoCloudApi.md index 9bb6973853c..d3fcf42ef10 100644 --- a/umbraco-cloud/set-up/project-settings/umbraco-cicd/UmbracoCloudApi.md +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/UmbracoCloudApi.md @@ -4,18 +4,43 @@ The Umbraco Cloud API serves as a publicly accessible endpoint that customers ca While its initial focus is on automating and managing deployments in Umbraco Cloud projects via the "Umbraco CI/CD Flow," future enhancements will broaden its capabilities to encompass a wider range of activities and options for Umbraco Cloud users. -For the scope of this discussion, we will concentrate solely on the endpoints associated with interactions within the Umbraco CI/CD Flow. +{% hint style="info" %} + +## Changes between endpoints for version 1 and 2 + +With the endpoints for version 2, you are given more control over the process. + +These are the most important differences between the V1 and V2 endpoints: + +- With version 2, it is possible to target a flexible environment or the left-most environment. +- More options are available when deploying. +- Simplified api call flow: Uploading an artifact is decoupled from the actual deployment. + +[Do you want to migrate from V1 to V2 endpoints?](./samplecicdpipeline/migrate.md) + +The V1 endpoints are still available, you can see the [V1 api documentation here](./v1-umbraco-cloud-api.md). + +{% endhint %} ## Getting started -To integrate Umbraco Cloud into your CI/CD pipeline, you'll need to make API calls to the following endpoint `https://api.cloud.umbraco.com`: +To integrate Umbraco Cloud into your CI/CD pipeline, you'll need to make API calls to the following endpoint [`https://api.cloud.umbraco.com`](https://api.cloud.umbraco.com): -* `/$projectId/deployments` -* `/$projectId/deployments/$deploymentId` -* `/$projectId/deployments/$deploymentId/package` -* `/$projectId/deployments/$latestCompletedDeploymentId/diff` +**Path for artifacts** -You will find relevant examples using `Curl` and `Powershell` in the sections below. +* `/v2/projects/$projectId/deployments/artifacts` + +**Paths for deployments** + +* `/v2/projects/$projectId/deployments` +* `/v2/projects/$projectId/deployments/$deploymentId` + +**Paths for querying deployments and fetching changes** + +* `/v2/projects/$projectId/deployments` +* `/v2/projects/$projectId/deployments/$latestCompletedDeploymentId/diff` + +You will find relevant examples using `HTTP Request Syntax` in the sections below. ### How to enable CI/CD Integrator in the Umbraco Cloud Portal @@ -30,322 +55,325 @@ The two elements to be used for the authentication are: By including the API key header in your HTTP requests, you ensure secure access to your Umbraco Cloud project's resources. -For enhanced security, it's crucial to store the provided API key in a secure location. Options include a variable group in Azure DevOps or using the Secrets feature in GitHub Actions. It's important to note that each API key is tightly coupled with a specific Umbraco Cloud project and can only be used for deployments related to that project. +For enhanced security, it's crucial to store the provided API key in a secure location. Options include a variable group in Azure DevOps or using the Secrets feature in GitHub Actions. +It's important to note that each API key is tightly coupled with a specific Umbraco Cloud project and can only be used for deployments related to that project. ### How to authenticate your requests -To authenticate your requests, include the API key in a custom HTTP header named API key. - -_PowerShell_ is a command-line shell and scripting language commonly used for automating tasks and managing configurations. It offers a versatile set of cmdlets that allow you to interact with APIs, manipulate files, and much more. Within the context of the Umbraco Cloud API, PowerShell can be employed to authenticate your requests by incorporating your unique API key. +To authenticate your API requests, you'll need to include your API key in a custom HTTP header named Umbraco-Cloud-Api-Key. -_Curl_ (Client URL) is a command-line tool commonly used for making HTTP requests. It's a versatile utility that allows you to interact with APIs, download files, and more. In the context of Umbraco Cloud API, curl can be used to authenticate your requests by including your unique API key. +{% tabs %} +{% tab title="HTTP Request Syntax" %} -To authenticate your API requests using curl, you'll need to include your API key in a custom HTTP header named Umbraco-Cloud-Api-Key. Here's how typical Powershell and curl commands would look for this purpose: +```http +GET https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments +Umbraco-Cloud-Api-Key : {{apiKey}} +``` -{% tabs %} +{% endtab %} {% tab title="Powershell" %} + ```powershell -Invoke-RestMethod -Uri $url -Headers @{ "Umbraco-Cloud-Api-Key" = $apiKey } -Method Get +Invoke-RestMethod -Uri https://api.cloud.umbraco.com/v2/projects/$projectId/deployments -Headers @{ "Umbraco-Cloud-Api-Key" = $apiKey } -Method Get ``` -{% endtab %} +{% endtab %} {% tab title="Curl" %} + ``` -curl -s -X GET $url -H "Umbraco-Cloud-Api-Key: $apiKey" +curl -s -X GET https://api.cloud.umbraco.com/v2/projects/$projectId/deployments -H "Umbraco-Cloud-Api-Key: $apiKey" ``` + {% endtab %} {% endtabs %} -## How to make a deployment to Umbraco Cloud using the Umbraco CI/CD API +## Deployment Artifacts -### Create the deployment +### Upload artifact -The Create Deployment endpoint initiates a new deployment and returns a unique `deploymentId`. This call serves as the initial step in the deployment process. It requires a `projectId` specified in the URL path and a commit message included in the request body. Essentially, this establishes the metadata necessary for initiating the deployment process. If a deployment is already underway, initiating a new one will be possible but should be avoided. +Artifacts are tied to a project. The uploaded artifact will be available to use in any deployment to an environment on that project. +The artifact needs to be a zip file with the source code needed to build your website. -To create a deployment, you'll need to make an HTTP POST request. The request body should contain a simple JSON object with the commit message: +[Read about artifact Best Practices](ArtifactBestPractice.md). -```json -{ - "commitMessage": "New dashboard for customer sales numbers" -} -``` +```http +@projectId = Get this value from the portal +@apiKey = Get this value from the portal +@description = my awesome optional description text +@version = my awesome optional version text +@file = path to file + filename -In Powershell, the command to initiate a new deployment would be as follows +POST https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments/artifacts +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: multipart/form-data; boundary=--TheFormDataBoundary -```powershell -... -$url = "https://api.cloud.umbraco.com/v1/projects/$projectId/deployments" -$headers = @{ - "Umbraco-Cloud-Api-Key" = $apiKey - "Content-Type" = "application/json" -} +----TheFormDataBoundary +Content-Disposition: form-data; name="file"; filename="package.zip" +content-type: application/octet-stream -$body = @{ - commitMessage = $commitMessage -} | ConvertTo-Json +< {{file}} +----TheFormDataBoundary +Content-Disposition: form-data; name="description" -Invoke-RestMethod -Uri $url -Headers $headers -Method Post -Body $body -``` - -In curl, the command to initiate a new deployment would be as follows +{{description}} +----TheFormDataBoundary +Content-Disposition: form-data; name="version" -```sh -... -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments" - -curl -s -X POST $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: application/json" \ - -d "{\"commitMessage\":\"$commitMessage\"}" +{{version}} +----TheFormDataBoundary-- ``` -Part of the returned response will be the actual `deploymentId`. The response from the API should be an HTTP 201 Created response including a `deploymentId`. This ID can be stored in the pipeline variables so it can be used in later steps. +Once the file is uploaded, you will get a response which follows the following JSON schema: ```json { - "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", - "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", - "projectAlias": "", - "deploymentState": "Created", - "updateMessage": "", - "errorMessage": "", - "created": "2023-05-02T07:16:46.4183912", - "lastModified": "2023-05-02T07:16:48.8544387", - "completed": null + "artifactId": string, + "fileName": string, + "blobUrl": string, + "filesize" : number, + "createdUtc": string, + "description": string, + "version": string } ``` -### Upload zip source file +### List artifacts -To deploy content to the Umbraco Cloud repository, you need to perform an HTTP POST request to the Umbraco Cloud API. The deployment content should be packaged as a ZIP file, which must mirror the expected structure of the Umbraco Cloud repository. This ZIP file should include all relevant files such as project and solution files, and compiled frontend code. If your setup includes a frontend project with custom elements, the build artifacts from that project should also be included in the ZIP file, and placed in the appropriate directory within the repository structure. +List artifacts uploaded related to a project. The endpoint is paged and accepts the options `skip` and `take`. +If `skip` is not supplied, its value will default to 0. +If `take` is not supplied, its value will default to 10. -The HTTP POST request should be made using the `multipart/form-data` content type. The request URL should incorporate both the `projectId` and `deploymentId` obtained from the previous step in the API path. +```http +@skip = 0 +@take = 10 +@projectId = Get this value from the portal +@apiKey = Get this value from the portal -The ZIP file must be structured the same way as described in the `Readme.md` included in all cloud projects starting from Umbraco 9. This also means if you need to change the name and/or structure of the project, you should follow the guide in the same Readme. +GET https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments/artifacts?skip={{skip}}&take={{take}} +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: application/json +``` -By adhering to these guidelines, you ensure that the uploaded content is an exact match with what is expected in the Umbraco Cloud repository, facilitating a seamless deployment process. +Response looks like: -The purpose of packaging your content into a ZIP file is to replace the existing content in the Umbraco Cloud repository upon unpackaging. This ensures that the repository is updated with the latest version of your project files. +```json +{ + "projectId": string, + "data": + [ + { + "artifactId": string, + "fileName": string, + "blobUrl": string, + "filesize" : number, + "createdUtc": string, + "description": string, + "version": string + } + ], + "totalItems": number, + "skippedItems": number, + "takenItems": number +} +``` -Make sure your ZIP archive does not contain .git folder. If you're using the `.zipignore` file, you can add the following line `.git/*` to exclude it. +## Deployments -#### A note about .gitignore +### Start the deployment -Umbraco Cloud environments are using git internally. This means you should be careful about the .gitignore file you add to the package. If you have “git ignored” build js assets locally, you need to handle this so that this is not being ignored in the cloud repository. +The Create Deployment endpoint starts a new deployment and returns a unique `deploymentId`. -**Note:** If the `.gitignore` file within the ZIP package does not exclude bin/ and obj/ directories, these will also be committed to the Umbraco Cloud repository. +Some new options are available to use in the request payload: -**Best Practice:** If you have frontend assets your local repository's .gitignore file will most likely differ from the one intended for the Umbraco Cloud repository, it's advisable to create a separate .cloud\_gitignore file. Include this file in the ZIP package and rename it to .gitignore before packaging. This ensures that only the necessary files and directories are uploaded and finally committed to the Umbraco Cloud repository. +- `artifactId` **REQUIRED** Id of the artifact you want to deploy +- `targetEnvironmentAlias` **REQUIRED** Alias of the environment you want to deploy to +- `commitMessage` **OPTIONAL** The commit message you want stamped in the Umbraco Cloud environment repository. +- `noBuildAndRestore` **OPTIONAL** Option to skip the restore and build in the isolated instance, default to false +- `skipVersionCheck` **OPTIONAL** Option to skip the version check in the isolated instance, default to false -In curl uploading the source file will be: +```http +@projectId = Get this value from the portal +@apiKey = Get this value from the portal +@targetEnvironmentAlias = left-most or flexible environment alias +@artifactId = Use artifact id from recent upload +@commitMessage = My awesome commit message for cloud +@noBuildAndRestore = false +@skipVersionCheck = false -```sh -... -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId/package" +POST https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: application/json -curl -s -X POST $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: multipart/form-data" \ - --form "file=@$file" +{ + "commitMessage": {{commitMessage}}, + "artifactId": {{artifactId}}, + "targetEnvironmentAlias": {{targetEnvironmentAlias}}, + "noBuildAndRestore": {{noBuildAndRestore}}, + "skipVersionCheck": {{skipVersionCheck}} +} ``` -The response of this call will be the same deployment object (in JSON) as when creating a new deployment, but the deploymentState should now be 'Pending': +The response from the API should be an HTTP 201 Created response including a `deploymentId`. ```json { - "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", - "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", - "projectAlias": "cicd-demo-site", - "deploymentState": "Pending", - "updateMessage":"Project information set\nDeployment pending\nDownloadUri set", - "errorMessage": "", - "created": "2023-05-02T07:16:46.4183912", - "lastModified": "2023-05-02T07:17:48.8544387", - "completed": null + "deploymentId": string, + "projectId": string, + "environmentAlias": string, + "deploymentState": string, + "deploymentStatusMessages": + [ + { + "message": string, + "timestampUtc": string + }, + ], + "createdUtc": string, + "completedUtc": string, + "modifiedUtc": string } ``` -### Start Deployment - -After the source file has been uploaded the deployment can be started. This will queue the deployment in the Umbraco Cloud services which will start the deployment as soon as possible. Starting the deployment is an HTTP PATCH request to the Umbraco Cloud API. `projectId` and the `deploymentId` from the previous step must be included in the path, and the deployment state set to 'Queued' in the request body. +You can use the deploymentId to query the Get Deployment status endpoint. -In curl starting a deployment will be: +{% hint style="info" %} +It is not recommended to enable the `skipVersionCheck`. This is to ensure that versions of the various Umbraco packages in the Cloud environment aren't overwritten by older versions. However, there may be instances where you would like to deploy an older artifact, and for those cases, it is possible to enable this setting to skip the step. -```sh -... -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId" - -curl -s -X PATCH $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: application/json" \ - -d "{\"deploymentState\": \"Queued\"}" -``` - -The response of this call will be the same deployment object (in JSON) as when creating a new deployment, but the deploymentState should now be 'Queued': - -```json -{ - "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", - "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", - "projectAlias": "cicd-demo-site", - "deploymentState": "Queued", - "updateMessage": "Project information set\nDeployment pending\nDownloadUri set\nDeployment queued", - "errorMessage": "", - "created": "2023-05-02T07:16:46.4183912", - "lastModified": "2023-05-02T07:18:48.8544387", - "completed": null -} -``` +Enabling the `noBuildAndRestore` only disabled the restore and build inside the isolated instance. Once the system pushes the source code to the environment, the regular Cloud flow takes over, and a build and publish operation will run as usual. One minute or more can be saved during the deployment process by enabling this option. +{% endhint %} ### Get Deployment status -To monitor the status of a deployment—whether it's completed, successful, or otherwise — you can periodically query the 'Get Deployment Status' API. This API endpoint is an HTTP GET request to the Umbraco Cloud API, and it requires both the `projectId` and the `deploymentId` obtained from previous steps to be included in the path. - -Deployments in Umbraco services can take varying amounts of time to complete. Therefore, it's advisable to poll this API at regular intervals to stay updated on the deployment's current state. For example, in a simple project, you might choose to poll the API every 15 seconds for a duration of 15 minutes. These figures are just a starting point; the optimal polling frequency and duration may differ for your specific pipeline. Based on initial experience, a 15-minute window generally suffices, but we welcome your feedback to fine-tune these parameters. +To monitor the status of a deployment, you can periodically query the 'Get Deployment Status' API. This API endpoint is an HTTP GET request to the Umbraco Cloud API, and it requires both the `projectId` and the `deploymentId` obtained from previous steps to be included in the path. -Using a curl command, polling for the deployment status would look like this: +Deployments in Umbraco services can take varying amounts of time to complete. Therefore, it's advisable to poll this API at regular intervals to stay updated on the deployment's current state. For example, in a simple project, you might choose to poll the API every 25 seconds for a duration of 15 minutes. These figures are just a starting point; the optimal polling frequency and duration may differ for your specific pipeline. -```sh -... -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId" +A new query parameter has been added to limit the deploymentStatusMessages. As a value for the query parameter you can use the `modifiedUtc` value from a previous response. -# Define a function to call API and check the status -function call_api { - response=$(curl -s -X GET $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: application/json") - echo "$response" - status=$(echo $response | jq -r '.deploymentState') -} +- `lastModifiedUtc` **OPTIONAL** Only show new deploymentStatusMessages since this point in time. -# Call API and check status -call_api -while [[ $status == "Pending" || $status == "InProgress" || $status == "Queued" ]]; do - echo "Status is $status, waiting 15 seconds..." - sleep 15 - call_api - if [[ $SECONDS -gt 900 ]]; then - echo "Timeout reached, exiting loop." - break - fi -done - -# Check final status -if [[ $status == "Completed" ]]; then - echo "Deployment completed successfully." -elif [[ $status == "Failed" ]]; then - echo "Deployment failed." - exit 1 -else - echo "Unexpected status: $status" - exit 1 -fi +```http +@projectId = Get this value from the portal +@apiKey = Get this value from the portal +@deploymentId = Get this value from the response of the endpoint above +@lastModifiedUtc = Get this value from a previous call to this endpoint +GET https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments/{{deploymentId}}?lastModifiedUtc={{lastModifiedUtc}} +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: application/json ``` -The response from this API call will return the same deployment object in JSON format as you would receive from other API interactions. Ultimately, the `deploymentState` field will indicate either 'Completed' or 'Failed'. Should the deployment fail, the 'ErrorMessage' field will provide additional details regarding the issue. +The response from this API call will return the same deployment object in JSON format as you would receive from other API interactions. Ultimately, the `deploymentState` field will indicate either 'Completed' or 'Failed'. +Should the deployment fail, check the `deploymentStatusMessages` for more information. ```json { - "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", - "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", - "projectAlias": "cicd-demo-site", - "deploymentState": "Completed", - "updateMessage":"Project information set\nDeployment pending\nDownloadUri set\nDeployment queued\nDeployment triggered\nDeployment started\nCheck blocking markers\nCreate updating marker\nGit Clone\nDownload update\nExtract Update\nChecking versions\nDeleting repository files\nCopying files to repository\nNuGet Restore\nDotnet Build\nGit Stage\nGit Commit\nGit Tag\nGit Push\nDelete updating marker\nDeployment successful", - "errorMessage": "", - "created": "2023-05-02T07:16:46.4183912", - "lastModified": "2023-05-02T07:20:48.8544387", - "completed": "2023-05-02T07:20:49.8544387" + "deploymentId": string, + "projectId": string, + "environmentAlias": string, + "deploymentState": string, + "deploymentStatusMessages": + [ + { + "message": string, + "timestampUtc": string + }, + ], + "createdUtc": string, + "completedUtc":string, + "modifiedUtc": string } ``` +## Query Deployments and fetch Changes + ### Get Deployments -The endpoint lets you retrieve a list of completed deployments. It can only list deployments that has been run through the api. +The endpoint lets you retrieve a list of completed deployments. It can only list deployments that have been run through the api. The API allows you to filter and limit the number of returned deployments using query parameters: -* _Skip_ : optional, zero or positive integer -* _Take_ : optional, zero or positive integer -* _Includenulldeployments_ : optional, boolean, defaults to true +- `Skip` : **OPTIONAL** zero or positive integer +- `Take` : **OPTIONAL** zero or positive integer +- `Includenulldeployments` : **OPTIONAL** boolean, defaults to true +- `TargetEnvironmentAlias` **OPTIONAL** Will query only for deployments to a specific environment. -The "skip" and "take" parameters, while optional, are always required to be used together. +The `skip` and `take` parameters, while optional, are always required to be used together. With `includenulldeployments` set to true, you will get all completed deployments, including those that did not create any new changes in the cloud repository. -To fetch the list of deployments using a curl command, the syntax would be as follows: - -```sh -... -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments?skip=0&take=1&includenulldeployments=false" +```http +@projectId = Get this value from the portal +@apiKey = Get this value from the portal +@skip = Defaults to zero +@take = Defaults to 100 +@includeNullDeployments = +@targetEnvironmentAlias = -response=$(curl -s -X GET $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: application/json") -latestDeploymentId=$(echo $response | jq -r '.deployments[0].deploymentId') +GET https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments?skip={{skip}}&take={{take}}&includeNullDeployments={{includeNullDeployments}}&targetEnvironmentAlias={{targetEnvironmentAlias}} +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: application/json ``` -The response from this API call will return an object containing a list of deployment objects. The deployment-objects are consistent with the structure used in other API responses. Deployments are listed in descending order based on their creation timestamp. +The response from this API call will return an object containing a list of deployment objects. The deployment objects are consistent with the structure used in other API responses. Deployments are listed in descending order based on their creation timestamp. ```json { - "projectId": "abcdef12-cef8-4e92-8887-ceb123456789", - "deployments": + "projectId": string, + "data": [ { - "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", - "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", - "projectAlias": "cicd-demo-site", - "deploymentState": "Completed", - "updateMessage": "...", - "errorMessage": "", - "created": "2023-05-02T07:16:46.4183912", - "lastModified": "2023-05-02T07:18:48.8544387", - "completed": "2023-05-02T07:22:48.8544387" + "id": string, + "artifactId": string, + "targetEnvironmentAlias": string, + "state": string, + "createdUtc": string, + "modifiedUtc": string, + "completedUtc": string, } - ] + ], + "totalItems": number, + "skippedItems": number, + "takenItems": number } ``` ### Get Deployment diff -Sometimes updates are done directly on the Umbraco Cloud repository. We encourage you to not do any actual work there, but auto-upgrades and environment changes will affect the umbraco-cloud-git-repos. To keep track of such changes, you can use the 'Get Deployment Diff' API. This API endpoint will provide you with a git-patch file detailing the changes between a specific deployment and the current state of the repository. To make this API call, you'll need to include both the `projectId` and the `deploymentId` of the deployment you want to check for differences against. This is a standard HTTP GET request. +Sometimes updates are done directly on the Umbraco Cloud repository. It is encouraged not to do any actual work there, but auto-upgrades and environment changes will affect the Umbraco Cloud git repositories. To keep track of such changes, you can use the 'Get Deployment Diff' API. This API endpoint will provide you with a git-patch file detailing the changes between a specific deployment and the current state of the repository. To make this API call, you'll need to include both the `projectId` and the `deploymentId` of the deployment you want to check for differences against. This is a standard HTTP GET request. -Using a curl command, fetching the potential differences would look like this: +The required query parameter has been added to the endpoint: -```sh -url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$latestCompletedDeploymentId/diff" -downloadFolder="tmp" -mkdir -p $downloadFolder # ensure folder exists +- `TargetEnvironmentAlias` **REQUIRED** The intended deployment target environment for the diff. -responseCode=$(curl -s -w "%{http_code}" -L -o "$downloadFolder/git-patch.diff" -X GET $url \ - -H "Umbraco-Cloud-Api-Key: $apiKey" \ - -H "Content-Type: application/json") +```http +@projectId = Get this value from the portal +@apiKey = Get this value from the portal +@deploymentId = +@targetEnvironmentAlias = -if [[ 10#$responseCode -eq 204 ]]; then # Http 204 No Content means that there are no changes - echo "No changes" - rm -fr $downloadFolder/git-patch.diff -elif [[ 10#$responseCode -eq 200 ]]; then # Http 200 downloads the file and set a few variables for pipeline - echo "Changes - check file - $downloadFolder/git-patch.diff" -else - echo "Unexpected status: $responseCode" - exit 1 -fi +GET https://api.cloud.umbraco.com/v2/projects/{{projectId}}/deployments/{{deploymentId}}/diff?targetEnvironmentAlias={{targetEnvironmentAlias}} +Umbraco-Cloud-Api-Key: {{apiKey}} +Content-Type: application/json ``` The API response will vary based on whether or not there are changes to report. If no changes are detected, you'll receive an HTTP 204 No Content status. On the other hand, if there are changes, the API will return an HTTP 200 OK status along with a git-patch file as the content. This git-patch file can then be applied to your local repository to sync it with the changes. -### Possible errors +{% hint style="info" %} +It is only possible to generate git-patch files when the selected `deploymentId` points to a deployment where the `targetEnvironmentAlias` then, is the same as in this request. +{% endhint %} + +## Possible errors When interacting with the Umbraco Cloud API, you may encounter various HTTP status codes that indicate the success or failure of your API request. Below is a table summarizing the possible status codes, their corresponding errors, and basic root causes to guide your troubleshooting: | Status Code | Error | Basic Root Cause | | ----------- | ------------------- | ----------------------------------------------------------------------------------- | -| 400 | BadRequest | Check the requested path, supplied headers and query-parameters | -| 401 | Unauthorized | Check the Project Id and Api Key | -| 404 | NotFound | Usually related to the supplied deploymentId in path not being found | +| 400 | BadRequest | Check the requested path, supplied headers, and query parameters | +| 401 | Unauthorized | Check the Project ID and Api Key | +| 404 | NotFound | Usually related to the supplied deploymentId in the path not being found | | 409 | Conflict | The state of the referenced deployment is not ready for the work you are requesting | | 500 | InternalServerError | InternalServerError | diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/README.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/README.md index 669ba33ea6f..3ad0ec8b854 100644 --- a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/README.md +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/README.md @@ -56,6 +56,22 @@ To get started with API interactions, you'll need to obtain your Project ID and The API key is tied to the specific project for which it is generated. Make sure to keep it secure in Azure or GitHub, as it will be used for all subsequent API interactions related to that project. {% endhint %} +## Getting environment aliases to target + +With the feature enabled a button called "CI/CD Environment Targets" becomes available. Clicking the button will show a modal with your environments and their aliases. +Next to the environment alias is a button you can click to copy the alias. + +

"Umbraco CI/CD Flow" section on the Advanced page.

+ +{% hint style="info" %} +If the alias is greyed out it is currently not a valid target through the Umbraco CI/CD flow api. + +Currently flexible environments and the left-most environment are considered valid targets. + +We are investigating the potential impact to allow CI/CD deployments to all environments. +{% endhint %} + + ## Sample pipelines Below we have a couple of examples of how to set up a CI/CD Pipeline using either Azure DevOps or GitHub Actions. @@ -83,3 +99,10 @@ Details the setup of a CI/CD pipeline using Azure DevOps. Details the setup of a CI/CD pipeline using GitHub Actions. * [GitHub Actions Sample](github-actions.md) + +## Samples for version 1 + +These are the guides for the old samples, relevant if you are using version 1 endpoints. + +* [Azure DevOps Sample](v1-azure-devops.md) +* [GitHub Actions Sample](v1-github-actions.md) \ No newline at end of file diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-azure-devops.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-azure-devops.md new file mode 100644 index 00000000000..8358a00f8ec --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-azure-devops.md @@ -0,0 +1,223 @@ +--- +hidden: true +--- + +# Azure DevOps + +Before setting up the pipeline in Azure DevOps, make sure that the following steps from the [Configuring a CI/CD pipeline](./) are done: + +* Pick a Cloud project +* Activate CI/CD Flow + +Next, you will need to define your pipeline in YAML and use it to interact with the Umbraco Cloud API. + +{% hint style="info" %} +The Umbraco CI/CD Team has created a sample pipeline for Azure DevOps. + +The Scripts are provided as is. This means that the scripts will do the bare minimum for a pipeline that is utilizing the CI/CD flow. + +You'll need to adapt and integrate the script into your own pipelines to gain the ability to do deployments to your Umbraco Cloud projects. + +The sample includes YAML-files and custom Powershell and Bash scripts to interact with the Umbraco Cloud API. + +You can get the samples for both `Azure DevOps` and `GitHub Actions` from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +Samples that target the endpoints described here are located in the V1 folder. +{% endhint %} + +{% hint style="warning" %} +Please be aware that since this involves using your custom pipeline, any issues that arise will need to be resolved by you. +{% endhint %} + +## Import Cloud project repository to Azure DevOps + +Go to your repositories in Azure DevOps and click on "Create a repository". + +* Create a new empty repository (don't add a README and don't add a .gitignore), and note down the clone URL. +* Go to the Umbraco Cloud Portal and clone your cloud project down locally. [This article](../../../working-locally.md#cloning-an-umbraco-cloud-project) describes how you can find the clone URL. +* Now working locally remove the Git Remote called `origin`, which currently points to Umbraco Cloud + +```sh +git remote remove origin +``` + +* Optionally rename branch `master` to `main` + +```sh +# optional step +git branch -m main +git symbolic-ref HEAD refs/heads/main +``` + +* Add a new remote called origin and pointing to the Azure DevOps clone URL and push + +```sh +git remote add origin https://{your-organization}@dev.azure.com/{your-organization}/{azure-project-scope}/_git/{your-repository} +git push -u origin --all +``` + +Now we can move on to setting up a pipeline. + +## Set up the Azure DevOps pipeline files + +While working with the project on your local machine, follow these steps to prepare the pipeline, using the [samples from the repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +{% hint style="info" %} +Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/). Click on "Code" and then choose "Download ZIP". Then unzip it and use the appropriate files from the V2 folder for the next steps. +{% endhint %} + +Select your preferred scripting language: + +{% tabs %} +{% tab title="Powershell" %} +For a pipeline that uses Powershell scripts you will need the following files: + +* From the root folder + * `cloud.zipignore` +* From the `powershell` folder + * `Get-LatestDeployment.ps1` + * `Get-ChangesById.ps1` + * `Apply-Patch.ps1` + * `New-Deployment.ps1` + * `Add-DeploymentPackage.ps1` + * `Start-Deployment.ps1` + * `Test-DeploymentStatus.ps1` +* From the `powershell/azuredevops` folder + * `azure-release-pipeline.yml` + * `cloud-sync.yml` + * `cloud-deployment.yml` + +**Do the following to prepare the pipeline:** + +* Copy the `cloud.zipignore` file to the root of your repository +* Make a copy of the `.gitignore` from your repository and call the copy `cloud.gitignore` + * Both files should be in the root of your repository + * In the bottom of the `.gitignore` file add the line `**/git-patch.diff` +* Also in the root, create a folder called `devops` +* Copy the 3 YAML files from the `powershell/azuredevops` folder into the `devops` folder +* Inside `devops` create an additional folder called `powershell` +* Copy the Powershell scripts from the `powershell` folder to the `powershell` folder +* **Note**: If you have not changed the branch to `main`, then in the `azure-release-pipeline.yaml` file change the branch from `main`to `master.` +* Commit all changes, and push to Azure DevOps +{% endtab %} + +{% tab title="Bash" %} +For a pipeline that uses Bash scripts you will need the following files: + +* From the root folder + * `cloud.zipignore` +* From the `bash` folder + * `get_latest_deployment.sh` + * `get_changes_by_id.sh` + * `apply-patch.sh` + * `create_deployment.sh` + * `upload_package.sh` + * `start_deployment.sh` + * `get_deployment_status.sh` +* From the `bash/azuredevops` folder + * `azure-release-pipeline.yml` + * `cloud-sync.yml` + * `cloud-deployment.yml` + +**Do the following to prepare the pipeline:** + +* Copy the `cloud.zipignore` file to the root of your repository +* Make a copy of the `.gitignore` from your repository and call the copy `cloud.gitignore` + * Both files should be in the root of your repository + * In the bottom of the `.gitignore` file add the line `**/git-patch.diff` +* Also in the root, create a folder called `devops` +* Copy the 3 YAML files from the `bash/azuredevops` folder into the `devops` folder +* Inside `devops` create an additional folder called `scripts` +* Copy the Bash scripts from the `bash` folder to the `scripts` folder +* **Note**: If you have not changed the branch to `main`, then in the `azure-release-pipeline.yaml` file change the branch from `main`to `master.` +* Commit all changes, and push to Azure DevOps +{% endtab %} +{% endtabs %} + +## Configure Azure DevOps + +The pipeline needs to know which Umbraco Cloud project to deploy to. In order to do this you will need the `Project ID` and the `API Key`. [This article](./#obtaining-the-project-id-and-api-key) describes how to get those values. + +* Now go to the repository in Azure and click on "Set up build". + +

Azure DevOps Repository

+ +* On the next screen click on "Existing Azure Pipelines YAML file" + +

Configure pipeline with existing YAML file

+ +* Select `main` (or `master` if you did not change the branch name) in Branch +* Select `/devops/azure-release-pipeline.yaml` in Path and continue + +

Select Branch and Path

+ +* Now you are on the "Review your pipeline YAML" screen + * Replace the `##Your project Id here##` with the Project Id you got from Umbraco Cloud Portal + * Click on "Variables" + +

Pipeline variables in Azure DevOps

+ +* Add the variable `umbracoCloudApiKey` with the value of the API Key you got from Umbraco Cloud Portal + +{% hint style="info" %} +It is recommended to handle the `API Key` as a secret. This can be done by ticking the "Keep this value secret" checkbox. + +Make the variable secret in Azure DevOps +{% endhint %} + +{% hint style="info" %} +You can customize the names for the variables as you like, however, you then need to rename the affected variables in `azure-release-pipeline.yaml`. + +Check the references to the variables in the yaml files match the variable syntaxes in the created variable. Example: `umbracoCloudApiKey` = `UMBRACOCLOUDAPIKEY`. +{% endhint %} + +When you click on "Save and Run" your first deployment will be triggered. Which means that Azure DevOps is set up with all the needed information to be able to deploy your Cloud project back to Umbraco Cloud. + +### Optional: Test the pipeline + +With everything set up, you may want to confirm that Umbraco Cloud reflects the changes you are sending via your pipeline. + +While working on your project locally, add a new Document type. + +* Commit the change to `main` branch (or `master` if you did not change the branch name) and push to your repository. +* The pipeline starts to run +* Once the pipeline is done log into Backoffice on your left-most environment in Umbraco Cloud +* Go to the Settings section and see that your new Document type has been deployed + +## High level overview of the pipeline components + +The mentioned scripts are provided as a starting point. It is recommended that you familiarize yourself with the scripts and with documentation related to how to use Azure DevOps. + +The scripts demonstrates the following: + +* How to sync your Azure DevOps repository with the [left-most project environment](../../../../deployment/) in Umbraco Cloud +* How to deploy changes to the left-most project environment in Umbraco Cloud + +### Main + +The `azure-release-pipeline.yaml` is the main pipeline, and is the one that will be triggered on a push to `main` branch. You can configure a different trigger behavior in this file. + +You can add your Build and Test stage between the `cloudSyncStage` and `cloudDeploymentStage` stages. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloudDeploymentStage` job will take care of packaging all your source code and upload to Umbraco Cloud. + +### Cloud-sync + +The `cloud-sync.yml` shows how you can sync your Azure DevOps repository with the left-most environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. + +If you don't want the pipeline to commit back to the triggering branch, this is where you need to change the pipeline. + +### Cloud-deployment + +The `cloud-deployment.yml` shows how you can deploy your repository to the left-most environment of your Cloud project. The sample shows how to prepare for deployment, request the deployment and wait for cloud to finish. + +There are a couple of things here to be aware of: + +* We are overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. +* We have a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. + +{% hint style="info" %} +If you have frontend assets that needs to be built (using npm/yarn or other tools), add the needed steps before `Zip Source Code`. This ensures that the fresh frontend assets will be part of the package to be sent to Umbraco Cloud. +{% endhint %} + +## Further information + +* [Azure Pipelines Documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/) diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-github-actions.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-github-actions.md new file mode 100644 index 00000000000..2128b0e9ef3 --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/V1-github-actions.md @@ -0,0 +1,240 @@ +--- +hidden: true +--- + +# GitHub Actions + +Before setting up the pipeline in GitHub, make sure that the following steps from the [Configuring a CI/CD pipeline](./) are done: + +* Pick a Cloud project +* Activate CI/CD Flow + +Next, you will need to define your pipeline in YAML and use it to interact with the Umbraco Cloud API. + +{% hint style="info" %} +The Umbraco CI/CD Team has created a sample pipeline for GitHub Actions. + +The Scripts are provided as is. This means that the scripts will do the bare minimum for a pipeline that is utilizing the CI/CD flow. + +You'll need to adapt and integrate the script to fit your pipelines to gain the ability to do deployments to your Umbraco Cloud projects. + +The sample includes YAML files and custom Powershell and Bash scripts to interact with the Umbraco Cloud API. + +You can get the samples for both `Azure DevOps` and `GitHub Actions` from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +Samples that target the endpoints described here are located in the V1 folder. +{% endhint %} + +{% hint style="warning" %} +Please be aware that since this involves using your custom pipeline, any issues that arise will need to be resolved by you. +{% endhint %} + +## Import Cloud project repository to GitHub + +Go to your repositories in GitHub and click on "New". + +* Create a new empty repository, and note down the clone URL. +* Go to the Umbraco Cloud Portal and clone your cloud project down locally. [This article](../../../working-locally.md#cloning-an-umbraco-cloud-project) describes how you can find the clone URL. +* Now working locally remove the Git Remote called `origin`, which points to Umbraco Cloud + +```sh +git remote remove origin +``` + +* Optionally rename branch `master` to `main` + +```sh +# optional step +git branch -m main +git symbolic-ref HEAD refs/heads/main +``` + +* Add a new remote called origin and pointing to the GitHub clone URL and push + +```sh +git remote add origin https://github.com/{your-organization}/{your-repository}.git +git push -u origin --all +``` + +Now we can move on to setting up a pipeline. + +## Set up GitHub repository variables + +The pipeline needs to know which Umbraco Cloud project to deploy to. In order to do this you will need the `Project ID` and the `API Key`. [This article](./#obtaining-the-project-id-and-api-key) describes how to get those values. + +* Now go to the repository in GitHub, and click on the Settings section. +* Expand secrets and variables in the left-hand menu titled `Security` and click on `Actions`. + +

Security and Actions menu GitHub

+ +* Create a `repository secret` called `UMBRACO_CLOUD_API_KEY` with the `API Key` value from the Umbraco Portal. +* Create another `repository secret` with the name `PROJECT_ID` and the `Project ID` value from the Umbraco Portal. + +{% hint style="info" %} +If you want to use other names for the secrets, you need to rename the `secrets` variables in each of `main.yml`'s jobs. + +```yaml +jobs: + cloud-sync: + uses: ./.github/workflows/cloud-sync.yml + secrets: + projectId: ${{ secrets.PROJECT_ID }} # change the part inside the curly braces + umbracoCloudApiKey: ${{ secrets.UMBRACO_CLOUD_API_KEY }} # change the part inside the curly braces + + cloud-deployment: + needs: cloud-sync + uses: ./.github/workflows/cloud-deployment.yml + secrets: + projectId: ${{ secrets.PROJECT_ID }} # change the part inside the curly braces + umbracoCloudApiKey: ${{ secrets.UMBRACO_CLOUD_API_KEY }} # change the part inside the curly braces +``` +{% endhint %} + +Now GitHub is set up with the needed information to be able to run a deployment back to Umbraco Cloud. + +Next up it setting up the actual pipeline. + +### Allow GitHub to commit to your repository + +The sample pipelines have a job called `cloud-sync`. This job is responsible for checking for changes in your Umbraco Cloud project, fetching them, and applying them back to your repository. In order for this to work, you need to give the `GITHUB_TOKEN` write permissions to the repository during workflow runs. + +This is how you can grant these permissions: + +* Working in your repository on `GitHub`, click on `Settings` in the top right +* In the left sidebar, click on `Actions` and then on `General` +* Scroll down to the `Workflow permissions` sections +* Select the `Read and write permissions` +* Click save + +

GitHub Workflow permissions

+ +## Set up the GitHub Actions pipeline + +While working with the project on your local machine, follow these steps to prepare the pipeline, using the [samples from the repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +{% hint style="info" %} +Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/). Click on "Code" and then choose "Download ZIP". Then unzip it and use the appropriate files from the V2 folder for the next steps. +{% endhint %} + +Select your preferred scripting language: + +{% tabs %} +{% tab title="Powershell" %} +For a pipeline that uses Powershell scripts you will need the following files: + +* From the root folder + * `cloud.zipignore` +* From the `powershell` folder + * `Get-LatestDeployment.ps1` + * `Get-ChangesById.ps1` + * `Apply-Patch.ps1` + * `New-Deployment.ps1` + * `Add-DeploymentPackage.ps1` + * `Start-Deployment.ps1` + * `Test-DeploymentStatus.ps1` +* From the `powershell/github` folder + * `main.yml` + * `cloud-sync.yml` + * `cloud-deployment.yml` + +**Do the following to prepare the pipeline:** + +* Copy the `cloud.zipignore` file to the root of your repository +* Make a copy of the `.gitignore` from your repository and call the copy `cloud.gitignore` + * Both files should be in the root of your repository + * In the bottom of the `.gitignore` file add the line `**/git-patch.diff` +* Also in the root, create a folder called `.github` +* Inside `.github` create two additional folders + * `workflows` + * `powershell` +* Copy the 3 YAML files from the `github` folder into the `workflows` folder +* Copy the Powershell scripts from the `powershell` folder to the `powershell` folder +* **Note**: If you have not changed the branch to `main`, then in the `main.yml` file change the branch from `main`to `master.` +* Commit the all changes, and push to GitHub +{% endtab %} + +{% tab title="Bash" %} +For a pipeline that uses Bash scripts you will need the following files: + +* From the root folder + * `cloud.zipignore` +* From the `bash` folder + * `get_latest_deployment.sh` + * `get_changes_by_id.sh` + * `apply-patch.sh` + * `create_deployment.sh` + * `upload_package.sh` + * `start_deployment.sh` + * `get_deployment_status.sh` +* From the `bash/github` folder + * `main.yml` + * `cloud-sync.yml` + * `cloud-deployment.yml` + +**Do the following to prepare the pipeline:** + +* Copy the `cloud.zipignore` file to the root of your repository +* Make a copy of the `.gitignore` from your repository and call the copy `cloud.gitignore` + * Both files should be in the root of your repository + * In the bottom of the `.gitignore` file add the line `**/git-patch.diff` +* Also in the root, create a folder called `.github` +* Inside `.github` create two additional folders + * `workflows` + * `scripts` +* Copy the 3 YAML files from the `github` folder into the `workflows` folder +* Copy the Bash scripts from the `bash` folder to the `scripts` folder +* **Note**: If you have not changed the branch to `main`, then in the `main.yml` file change the branch from `main`to `master.` +* Commit the all changes, and push to GitHub +{% endtab %} +{% endtabs %} + +The push will start a new pipeline run. + +### Optional: Test the pipeline + +With everything set up, you may want to confirm that Umbraco Cloud reflects the changes you are sending via your pipeline. + +While working on you project locally, add a new Document type. + +* Commit the change to `main` branch (or `master` if you did not change the branch name) and push to your repository. +* The pipeline starts to run +* Once the pipeline is done log into Backoffice on your left-most environment in Umbraco Cloud +* Go to the Settings section and see that your new Document type has been deployed + +## High level overview of the pipeline components + +The mentioned scripts are provided as a starting point. It is recommended that you familiarize yourself with the scripts and with documentation related to how to use GitHub Actions. + +The scripts demonstrates the following: + +* How to sync your GitHub repository with the [left-most project environment](../../../../deployment/) in Umbraco Cloud +* How to deploy changes to the left-most project environment in Umbraco Cloud + +### Main + +The `main.yml` is the main pipeline, and is the one that will be triggered on a push to `main` branch. You can configure a different trigger behavior in this file. + +You can add your Build and Test jobs between the `cloud-sync` and `cloud-deployment` jobs. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloud-deployment` job will take care of packaging all your source code and upload to Umbraco Cloud. + +### Cloud-sync + +The `cloud-sync.yml` shows how you can sync your GitHub repository with the left-most environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. + +If you don't want the pipeline to commit back to the triggering branch, this is where you need to change the pipeline. + +### Cloud-deployment + +The `cloud-deployment.yml` show how you can deploy your repository to the left-most environment of your Cloud project. The sample shows how to prepare for deployment, request the deployment and wait for cloud to finish. + +There are a couple of things here to be aware of: + +* We are overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. +* We have a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. + +{% hint style="info" %} +If you have frontend assets that needs to be built (using npm/yarn or other tools), add the needed steps before `Zip Source Code`. This ensures that the fresh frontend assets will be part of the package to be sent to Umbraco Cloud. +{% endhint %} + +## Further information + +* [GitHub Actions Documentation](https://docs.github.com/en/actions) diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/advanced-multiple-targets.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/advanced-multiple-targets.md new file mode 100644 index 00000000000..fb70c3721e2 --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/advanced-multiple-targets.md @@ -0,0 +1,149 @@ +# Deploy to multiple targets + +In this example, you will learn how to target deployments to more than one environment. + +The sample will enable you to work on two different branches, where each branch will deploy to a different environment. + +{% hint style="info" %} +With the CI/CD flow, you can trigger deployments to multiple environments at the same time. + +If there is already a deployment in progress to a named environment, it will not be possible to trigger another until the first is done. +{% endhint %} + +{% tabs %} +{% tab title="Azure DevOps" %} + +Replace the `azure-release-pipeline.yaml` with the one called `azure-release-pipeline-more-targets.yaml`. It's okay to rename `azure-release-pipeline-more-targets.yaml`. + +Its locations in the sample scripts are: + +- Bash: `/V2/bash/azuredevops/advanced` +- PowerShell: `/V2/powershell/azuredevops/advanced` + +Make sure you don't have multiple YAML files that contain triggers (unless you designed your pipeline's workflow that way). + +Now you need the aliases of the environments you want to target. + +Insert the aliases into the placeholders in `azure-release-pipeline-more-targets.yaml`, the values you need to replace are: + +- `##Your target environment alias here##` +- `##Your other target environment alias here##` + +Remember to fix the projectId placeholder if you haven't already: `##Your project ID here##` + +Next, look at the triggers for the pipeline: + +```yml +# Trigger when committing to main or flexible branch +trigger: + batch: true + branches: + include: + - main + - flexible +``` + +Here, you can change when a deployment is triggered based on which branch is pushed to. + +The pipeline needs to resolve the target based on the triggering branch, which is done in the following code. + +```yml +stages: + # resolve which environment to deploy to based on triggering branch + - stage: resolveTarget + displayName: Resolve Target Environment + jobs: + - job: setTargetEnvironment + steps: + - script: | + echo "Triggering branch: $(Build.SourceBranchName)" + if [ "$(Build.SourceBranchName)" = "main" ]; then + echo "Target is: $(targetEnvironmentAlias)" + echo "##vso[task.setvariable variable=targetEnvironment;isOutput=true]$(targetEnvironmentAlias)" + elif [ "$(Build.SourceBranchName)" = "flexible" ]; then + echo "Target is: $(flexibleTargetEnvironmentAlias)" + echo "##vso[task.setvariable variable=targetEnvironment;isOutput=true]$(flexibleTargetEnvironmentAlias)" + else + echo "no target environment defined for branch: $(Build.SourceBranchName)" + exit 1 + fi + name: setTargetEnvironmentValue +``` + +The triggering branch is evaluated in the statement `if [ "$(Build.SourceBranchName)" = "main" ]; then` or `elif [ "$(Build.SourceBranchName)" = "flexible" ]; then`. + +The code will write which alias is targeted and write a pipeline variable (`targetEnvironment`). This variable is then used by later steps. + +When updating the triggering branch names, it must be updated in the two mentioned places: In the trigger and in the script. + +{% endtab %} +{% tab title="GitHub Actions" %} + +Replace the `main.yml` with the one called `main-more-targets.yml`. It's okay to rename `main-more-targets.yml`. + +Its locations in the sample scripts are: + +- Bash: `/V2/bash/github/advanced` +- PowerShell: `/V2/powershell/github/advanced` + +Make sure you don't have multiple YAML files that contain triggers (unless you designed your pipeline's workflow that way). + +Now you need the aliases of the environments you want to target. + +* Now go to the repository in GitHub, and click on the Settings section. +* Expand secrets and variables in the left-hand menu titled `Security` and click on `Actions`. +* Now go to the **Variables** tab +* Add a `repository variable` called `FLEXIBLE_ENVIRONMENT_ALIAS` and enter the environment alias you selected earlier. + +If you followed the [GitHub guide](github-actions.md) you should already have a variable called `TARGET_ENVIRONMENT_ALIAS`. + +Next, look at the triggers for the pipeline: + +```yml +# Trigger when committing to main branch +on: + push: + branches: + - main + - flexible + workflow_dispatch: # Allow manual triggering of the workflow +``` + +Here you can change when a deployment is trigger based on which branch is pushed to. + +The pipeline needs to resolve the target based on the triggering branch, which is done in the following code. + +```yml +jobs: + # resolve which environment to deploy to based on triggering branch + set-env: + runs-on: ubuntu-latest + outputs: + targetEnvironmentAlias: ${{ steps.set.outputs.targetEnvironmentAlias }} + steps: + - name: Resolve Target Environment + id: set + run: | + echo "Triggering branch: ${{ github.ref_name }}" + if [[ "${{ github.ref_name }}" == "main" ]]; then + echo "Target is: $leftmostMainline" + echo "targetEnvironmentAlias=$leftmostMainline" >> $GITHUB_OUTPUT + elif [ "${{ github.ref_name }}" = "flexible" ]; then + echo "Target is: $flexible" + echo "targetEnvironmentAlias=$flexible" >> $GITHUB_OUTPUT + else + echo "no target environment defined for branch: $(Build.SourceBranchName)" + exit 1 + fi + env: + leftmostMainline: ${{ vars.TARGET_ENVIRONMENT_ALIAS}} + flexible: ${{ vars.FLEXIBLE_ENVIRONMENT_ALIAS }} +``` + +The triggering branch is evaluated in the statement `if [[ "${{ github.ref_name }}" == "main" ]]; then` or `elif [ "${{ github.ref_name }}" = "flexible" ]; then`. +The code will write which alias is targeted and write a pipeline variable (`targetEnvironmentAlias`). This variable is then used by later jobs. + +When updating the triggering branch names, it must be updated in the two mentioned places: In the trigger and in the script. + +{% endtab %} +{% endtabs %} diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/artifact-best-practice.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/artifact-best-practice.md new file mode 100644 index 00000000000..2bec987bdd3 --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/artifact-best-practice.md @@ -0,0 +1,38 @@ +# Deployment Artifact best practice + +The zip package you are deploying needs to contain all things that are normally present in an Umbraco Cloud environment repository. + +Every new Umbraco Cloud project contains a `readme.md` file which explains the structure and how you can adapt it to suit your needs. + +The sample scripts on GitHub include a way to package the zip. As the scripts are samples, they show a universal way to do this, which works well for most people. But not all projects are alike, and you may not want to use that particular approach. + +## Do not include .NET Binaries + +Don’t include any binary build artifacts coming from the .NET build/publish process. + +The general deployment process on Umbraco Cloud needs the source code, and the system will rebuild it once it is pushed back to the environment. + +## Do not include the `.git` directory + +The folder will be ignored in the isolated instance, including the extra megabytes will slow down the deployment process. + +Also, consider the artifact size limitation below. + +## Do include the finished frontend assets + +If you are using modern frontend build tools, only include the finished frontend assets that are needed. There is no need to include JavaScript or TypeScript source files if you need to build the frontend. + +## Keep the Artifact as small as possible + +It is good practice to keep the zipped artifact as small as possible. + +* Large files will slow down the underlying git operations and, therefore, also the deployment process. + * Do not include large files like pictures and PDFs in the artifact. + * Large files need to be uploaded to the blob storage connected to your environment. +* Remove old and leftover code from the artifact. + * Orphaned `.csproj` files with outdated package references are a common cause for issues in the deployment process. + +Size limitations to consider: + +- The version 1 endpoints will allow file sizes up to 128 MB. +- In version 2 endpoints, the size limit is increased to 256 MB. diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/azure-devops.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/azure-devops.md index 2bdd89fd62a..d0ba73113a2 100644 --- a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/azure-devops.md +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/azure-devops.md @@ -23,6 +23,8 @@ You'll need to adapt and integrate the script into your own pipelines to gain th The sample includes YAML-files and custom Powershell and Bash scripts to interact with the Umbraco Cloud API. You can get the samples for both `Azure DevOps` and `GitHub Actions` from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +Samples that target the endpoints described here are located in the V2 folder. {% endhint %} {% hint style="warning" %} @@ -63,7 +65,7 @@ Now we can move on to setting up a pipeline. While working with the project on your local machine, follow these steps to prepare the pipeline, using the [samples from the repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). {% hint style="info" %} -Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/tree/main). Click on "Code" and then choose "Download ZIP". Then unzip it and use those files for the next steps. +Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/). Click on "Code" and then choose "Download ZIP". Then unzip it and use the appropriate files from the V2 folder for the next steps. {% endhint %} Select your preferred scripting language: @@ -78,13 +80,13 @@ For a pipeline that uses Powershell scripts you will need the following files: * `Get-LatestDeployment.ps1` * `Get-ChangesById.ps1` * `Apply-Patch.ps1` - * `New-Deployment.ps1` - * `Add-DeploymentPackage.ps1` + * `Add-DeploymentArtifact.ps1` * `Start-Deployment.ps1` * `Test-DeploymentStatus.ps1` * From the `powershell/azuredevops` folder * `azure-release-pipeline.yml` * `cloud-sync.yml` + * `cloud-artifact.yml` * `cloud-deployment.yml` **Do the following to prepare the pipeline:** @@ -110,13 +112,13 @@ For a pipeline that uses Bash scripts you will need the following files: * `get_latest_deployment.sh` * `get_changes_by_id.sh` * `apply-patch.sh` - * `create_deployment.sh` - * `upload_package.sh` + * `upload_artifact.sh` * `start_deployment.sh` * `get_deployment_status.sh` * From the `bash/azuredevops` folder * `azure-release-pipeline.yml` * `cloud-sync.yml` + * `cloud-artifact.yml` * `cloud-deployment.yml` **Do the following to prepare the pipeline:** @@ -138,6 +140,8 @@ For a pipeline that uses Bash scripts you will need the following files: The pipeline needs to know which Umbraco Cloud project to deploy to. In order to do this you will need the `Project ID` and the `API Key`. [This article](./#obtaining-the-project-id-and-api-key) describes how to get those values. +You will also need the alias of the environment you want to target. [This article](./#getting-environment-aliases-to-target) described how you can see a list of environments you can target here. Note the environment alias you want to target. + * Now go to the repository in Azure and click on "Set up build".

Azure DevOps Repository

@@ -153,6 +157,7 @@ The pipeline needs to know which Umbraco Cloud project to deploy to. In order to * Now you are on the "Review your pipeline YAML" screen * Replace the `##Your project Id here##` with the Project Id you got from Umbraco Cloud Portal + * Replace the `##Your target environment alias here##` with the alias of the environment you want to target * Click on "Variables"

Pipeline variables in Azure DevOps

@@ -186,38 +191,54 @@ While working on your project locally, add a new Document type. ## High level overview of the pipeline components -The mentioned scripts are provided as a starting point. It is recommended that you familiarize yourself with the scripts and with documentation related to how to use Azure DevOps. +The mentioned scripts are provided as a starting point. +It is recommended that you familiarize yourself with the scripts and with documentation related to how to use Azure DevOps. The scripts demonstrates the following: -* How to sync your Azure DevOps repository with the [left-most project environment](../../../../deployment/) in Umbraco Cloud -* How to deploy changes to the left-most project environment in Umbraco Cloud +* How to sync your Azure DevOps repository with an environment in Umbraco Cloud via the environment alias +* How to prepare and upload an artifact that can be used for a deployment +* How to deploy changes to an environment in Umbraco Cloud, targeted via the environment alias ### Main -The `azure-release-pipeline.yaml` is the main pipeline, and is the one that will be triggered on a push to `main` branch. You can configure a different trigger behavior in this file. +The `azure-release-pipeline.yaml` is the main pipeline, and is the one that will be triggered on a push to the `main` branch in your repository. You can configure a different trigger behavior in this file. + +You can add your Build and Test stage between the `cloudSyncStage` and `cloudPrepareArtifact` stages. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloudPrepareArtifact` job will take care of packaging all your source code and upload to Umbraco Cloud. -You can add your Build and Test stage between the `cloudSyncStage` and `cloudDeploymentStage` stages. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloudDeploymentStage` job will take care of packaging all your source code and upload to Umbraco Cloud. +Make sure that you checkout the potentially updated code if you add Build and Test steps. ### Cloud-sync -The `cloud-sync.yml` shows how you can sync your Azure DevOps repository with the left-most environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. +The `cloud-sync.yml` shows how you can sync your Azure DevOps repository with the targeted environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. If you don't want the pipeline to commit back to the triggering branch, this is where you need to change the pipeline. -### Cloud-deployment +### Cloud-artifact -The `cloud-deployment.yml` shows how you can deploy your repository to the left-most environment of your Cloud project. The sample shows how to prepare for deployment, request the deployment and wait for cloud to finish. +The `cloud-artifact.yml` shows how you can prepare and package an artifact and finally upload it to Umbraco Cloud. There are a couple of things here to be aware of: -* We are overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. -* We have a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. +* The sample is overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. +* The sample contains a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. + +If you want to customize the artifact take a look at [Artifact Best Practice](../artifact-best-practice.md). + +### Cloud-deployment + +The `cloud-deployment.yml` shows how you can deploy to a named environment of your Cloud project. The sample shows how to request the deployment and wait for cloud to finish the operation. {% hint style="info" %} -If you have frontend assets that needs to be built (using tools like npm/yarn or others), you should add the needed steps before `Zip Source Code`. This is to ensure that the fresh frontend assets will be part of the package to be sent to Umbraco Cloud. +If you have frontend assets that needs to be built (using tools like npm/yarn or others), you should add the needed steps before `cloudPrepareArtifact`. This is to ensure that the fresh frontend assets will be part of the package to be sent to Umbraco Cloud. {% endhint %} +## Next step + +Please follow the above guide first. + +* [Deploy to multiple targets](advanced-multiple-targets.md) + ## Further information * [Azure Pipelines Documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/) diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/github-actions.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/github-actions.md index 70313b96068..33f92d5f78b 100644 --- a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/github-actions.md +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/github-actions.md @@ -14,15 +14,17 @@ Before setting up the pipeline in GitHub, make sure that the following steps fro Next, you will need to define your pipeline in YAML and use it to interact with the Umbraco Cloud API. {% hint style="info" %} -The Umbraco CI/CD Team has created a sample pipeline for Azure DevOps. +The Umbraco CI/CD Team has created a sample pipeline for GitHub Actions. The Scripts are provided as is. This means that the scripts will do the bare minimum for a pipeline that is utilizing the CI/CD flow. -You'll need to adapt and integrate the script to fit your pipelines to gain the ability to do deployments to your Umbraco Cloud projects. +You'll need to adapt and integrate the script into your own pipelines to gain the ability to do deployments to your Umbraco Cloud projects. -The sample includes YAML files and custom Powershell and Bash scripts to interact with the Umbraco Cloud API. +The sample includes YAML-files and custom Powershell and Bash scripts to interact with the Umbraco Cloud API. You can get the samples for both `Azure DevOps` and `GitHub Actions` from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). + +Samples that target the endpoints described here are located in the V2 folder. {% endhint %} {% hint style="warning" %} @@ -62,6 +64,8 @@ Now we can move on to setting up a pipeline. The pipeline needs to know which Umbraco Cloud project to deploy to. In order to do this you will need the `Project ID` and the `API Key`. [This article](./#obtaining-the-project-id-and-api-key) describes how to get those values. +You will also need the alias of the environment you want to target. [This article](./#getting-environment-aliases-to-target) described how you can see a list of environments you can target here. Note the environment alias you want to target. + * Now go to the repository in GitHub, and click on the Settings section. * Expand secrets and variables in the left-hand menu titled `Security` and click on `Actions`. @@ -70,8 +74,11 @@ The pipeline needs to know which Umbraco Cloud project to deploy to. In order to * Create a `repository secret` called `UMBRACO_CLOUD_API_KEY` with the `API Key` value from the Umbraco Portal. * Create another `repository secret` with the name `PROJECT_ID` and the `Project ID` value from the Umbraco Portal. +Now go to the **Variables** tab +* Create a `repository variable` called `TARGET_ENVIRONMENT_ALIAS` and enter the environment alias you selected earlier. + {% hint style="info" %} -If you want to use other names for the secrets, you need to rename the `secrets` variables in each of `main.yml`'s jobs. +If you want to use other names for the secrets and variables, you need to rename the `secrets` and `with` variables in each of `main.yml`'s jobs. ```yaml jobs: @@ -80,6 +87,14 @@ jobs: secrets: projectId: ${{ secrets.PROJECT_ID }} # change the part inside the curly braces umbracoCloudApiKey: ${{ secrets.UMBRACO_CLOUD_API_KEY }} # change the part inside the curly braces + with: + targetEnvironmentAlias: ${{ vars.TARGET_ENVIRONMENT_ALIAS }} # change the part inside the curly braces + + cloud-artifact: + uses: ./.github/workflows/cloud-artifact.yml + secrets: + projectId: ${{ secrets.PROJECT_ID }} # change the part inside the curly braces + umbracoCloudApiKey: ${{ secrets.UMBRACO_CLOUD_API_KEY }} # change the part inside the curly braces cloud-deployment: needs: cloud-sync @@ -87,7 +102,9 @@ jobs: secrets: projectId: ${{ secrets.PROJECT_ID }} # change the part inside the curly braces umbracoCloudApiKey: ${{ secrets.UMBRACO_CLOUD_API_KEY }} # change the part inside the curly braces -``` + with: + targetEnvironmentAlias: ${{ vars.TARGET_ENVIRONMENT_ALIAS }} # change the part inside the curly braces +``` {% endhint %} Now GitHub is set up with the needed information to be able to run a deployment back to Umbraco Cloud. @@ -113,7 +130,7 @@ This is how you can grant these permissions: While working with the project on your local machine, follow these steps to prepare the pipeline, using the [samples from the repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples). {% hint style="info" %} -Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/tree/main). Click on "Code" and then choose "Download ZIP". Then unzip it and use those files for the next steps. +Download the provided sample scripts as ZIP from the [GitHub repository](https://github.com/umbraco/Umbraco.Cloud.CICDFlow.Samples/). Click on "Code" and then choose "Download ZIP". Then unzip it and use the appropriate files from the V2 folder for the next steps. {% endhint %} Select your preferred scripting language: @@ -128,13 +145,13 @@ For a pipeline that uses Powershell scripts you will need the following files: * `Get-LatestDeployment.ps1` * `Get-ChangesById.ps1` * `Apply-Patch.ps1` - * `New-Deployment.ps1` - * `Add-DeploymentPackage.ps1` + * `Add-DeploymentArtifact.ps1` * `Start-Deployment.ps1` * `Test-DeploymentStatus.ps1` * From the `powershell/github` folder * `main.yml` * `cloud-sync.yml` + * `cloud-artifact.yml` * `cloud-deployment.yml` **Do the following to prepare the pipeline:** @@ -162,13 +179,13 @@ For a pipeline that uses Bash scripts you will need the following files: * `get_latest_deployment.sh` * `get_changes_by_id.sh` * `apply-patch.sh` - * `create_deployment.sh` - * `upload_package.sh` + * `upload_artifact.sh` * `start_deployment.sh` * `get_deployment_status.sh` * From the `bash/github` folder * `main.yml` * `cloud-sync.yml` + * `cloud-artifact.yml` * `cloud-deployment.yml` **Do the following to prepare the pipeline:** @@ -194,7 +211,7 @@ The push will start a new pipeline run. With everything set up, you may want to confirm that Umbraco Cloud reflects the changes you are sending via your pipeline. -While working on you project locally, add a new Document type. +While working on your project locally, add a new Document type. * Commit the change to `main` branch (or `master` if you did not change the branch name) and push to your repository. * The pipeline starts to run @@ -203,38 +220,54 @@ While working on you project locally, add a new Document type. ## High level overview of the pipeline components -The mentioned scripts are provided as a starting point. It is recommended that you familiarize yourself with the scripts and with documentation related to how to use GitHub Actions. +The mentioned scripts are provided as a starting point. +It is recommended that you familiarize yourself with the scripts and with documentation related to how to use GitHub Actions. The scripts demonstrates the following: -* How to sync your GitHub repository with the [left-most project environment](../../../../deployment/) in Umbraco Cloud -* How to deploy changes to the left-most project environment in Umbraco Cloud +* How to sync your GitHub repository with an environment in Umbraco Cloud via the environment alias +* How to prepare and upload an artifact that can be used for a deployment +* How to deploy changes to an environment in Umbraco Cloud, targeted via the environment alias ### Main The `main.yml` is the main pipeline, and is the one that will be triggered on a push to `main` branch. You can configure a different trigger behavior in this file. -You can add your Build and Test jobs between the `cloud-sync` and `cloud-deployment` jobs. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloud-deployment` job will take care of packaging all your source code and upload to Umbraco Cloud. +You can add your Build and Test jobs between the `cloud-sync` and `cloud-artifact` jobs. Keep in mind that you do not need to retain the dotnet build artifact for upload later. The `cloud-artifact` job will take care of packaging all your source code and upload to Umbraco Cloud. + +Make sure that you checkout the potentially updated code if you add Build and Test steps. ### Cloud-sync -The `cloud-sync.yml` shows how you can sync your GitHub repository with the left-most environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. +The `cloud-sync.yml` shows how you can sync your GitHub repository with the targeted environment of your Cloud project. In this sample, it accepts any change from the API and applies and commits it back to the branch which triggered the pipeline. However the commit does not trigger the pipeline again. If you don't want the pipeline to commit back to the triggering branch, this is where you need to change the pipeline. -### Cloud-deployment +### Cloud-artifact -The `cloud-deployment.yml` show how you can deploy your repository to the left-most environment of your Cloud project. The sample shows how to prepare for deployment, request the deployment and wait for cloud to finish. +The `cloud-artifact.yml` shows how you can prepare and package an artifact and finally upload it to Umbraco Cloud. There are a couple of things here to be aware of: -* We are overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. -* We have a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. +* The sample is overwriting the `.gitignore` file with `cloud.gitignore`. This is a way to accommodate your gitignore-needs when working locally. For instance you might want to ignore frontend builds, but you want them build and published to cloud. +* The sample contains a special `cloud.zipignore` file. This is a convenient way to tell the pipeline which files **not** to include when creating the zip package to send to cloud. + +If you want to customize the artifact take a look at [Artifact Best Practice](../artifact-best-practice.md). + +### Cloud-deployment + +The `cloud-deployment.yml` shows how you can deploy to a named environment of your Cloud project. The sample shows how to request the deployment and wait for cloud to finish the operation. {% hint style="info" %} -If you have frontend assets that needs to be build (using tools like npm/yarn or others), you should add the needed steps before `Zip Source Code`. This is to ensure that the fresh frontend assets will be part of the package to be sent to cloud. +If you have frontend assets that needs to be built (using tools like npm/yarn or others), you should add the needed steps before `cloud-artifact`. This is to ensure that the fresh frontend assets will be part of the package to be sent to Umbraco Cloud. {% endhint %} +## Next step + +Please follow the above guide first. + +* [Deploy to multiple targets](advanced-multiple-targets.md) + ## Further information * [GitHub Actions Documentation](https://docs.github.com/en/actions) diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/migrate.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/migrate.md new file mode 100644 index 00000000000..391e34d4cc4 --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/samplecicdpipeline/migrate.md @@ -0,0 +1,127 @@ +# Migrate from version 1 to version 2 + +The original flow has been improved based on the feedback received from users of the feature. + +This article covers how to migrate from version 1 samples to version 2. + +{% hint style="info" %} +Be advised that both scripts and pipeline files have changes. + +Familiarize yourself with the new samples. + +If you customized the flow or the version 1 scripts, take extra care to incorporate your changes. +{% endhint %} + +You can keep using the old endpoints and samples, but you will miss out on the enhancements. There are currently no plans to deprecate the version 1 endpoints. + +## What has changed? + +The biggest enhancement is the ability to target different environments. You can now target the flexible and the leftmost mainline environment. + +The new endpoints are created to accommodate this enhancement, meaning you will have to supply a target environment alias in some requests. + +The initial flow has been slightly changed. The upload of a deployment package is no longer tied to a "deployment-meta", but is now a separate step. Every uploaded artifact can be queried by the API, similar to querying deployments via the API. + +When you request a deployment, you now also need to supply an `artifactId`. More options are available when deploying. + +To showcase how to use the version 2 endpoints and flow, updated samples are provided. + +## Migrate Azure DevOps + +Start by deleting the scripts and YAML files you initially got from the CI/CD samples: + +- Delete the YAML: + - `azure-release-pipeline.yaml` + - `cloud-sync.yml` + - `cloud-deployment.yml` + +You probably only have either PowerShell or Bash. + +- PowerShell files to delete: + - `Add-DeploymentPackage.ps1` + - `Apply-Patch.ps1` + - `Get-ChangesById.ps1` + - `Get-LatestDeployment.ps1` + - `New-Deployment.ps1` + - `Start-Deployment.ps1` + - `Test-Deployment.ps1` +- Bash files to delete: + - `apply_patch.sh` + - `create_deployment.sh` + - `get_changes_by_id.sh` + - `get_deployment_status.sh` + - `get_latest_deployment.sh` + - `start_deployment.sh` + - `upload_package.sh` + +Copy the scripts from the sample repository's version 2 folder to the corresponding folder in your repo: + +- If you prefer PowerShell: + - All `.ps1` files in `V2/powershell` should be copied to `devops/powershell` + - All `.yaml/.yml` files in `V2/powershell/azuredevops` should be copied to `devops` +- If you prefer Bash: + - All `.sh` files in `V2/bash` should be copied to `devops/scripts` + - All `.yaml/.yml` files in `V2/bash/azuredevops` should be copied to `devops` + +Now you need some important values: Project ID and Target environment alias. + +- [How to get the project id](./README.md#obtaining-the-project-id-and-api-key) +- [How to get the environment alias](./README.md#getting-environment-aliases-to-target) + +Open the `azure-release-pipeline.yaml` in your favorite editor. + +Replace `##Your project Id here##` with the project ID and the value `##Your target environment alias here#` with the environment alias. + +You can use any of the available aliases, but to get similar functionality as before, select the environment described as `Leftmost mainline`. + +## Migrate GitHub + +Start by deleting the scripts and YAML files you initially got from the CI/CD samples: + +- Delete the YAML: + - `main.yml` + - `cloud-sync.yml` + - `cloud-deployment.yml` + +You probably only have either PowerShell or Bash. + +- PowerShell files to delete: + - `Add-DeploymentPackage.ps1` + - `Apply-Patch.ps1` + - `Get-ChangesById.ps1` + - `Get-LatestDeployment.ps1` + - `New-Deployment.ps1` + - `Start-Deployment.ps1` + - `Test-Deployment.ps1` +- Bash files to delete: + - `apply_patch.sh` + - `create_deployment.sh` + - `get_changes_by_id.sh` + - `get_deployment_status.sh` + - `get_latest_deployment.sh` + - `start_deployment.sh` + - `upload_package.sh` + +Now copy the scripts from the sample repository's V2 folder to the corresponding folder in you repo: + +- If you prefer PowerShell: + - All `.ps1` files in `V2/powershell` should be copied to `.github/powershell` + - All `.yaml/.yml` files in `V2/powershell/github` should be copied to `.github/workflows` +- If you prefer Bash: + - All `.sh` files in `V2/bash` should be copied to `.github/scripts` + - All `.yaml/.yml` files in `V2/bash/github` should be copied to `.github/workflows` + +Now we need one important value: Target environment alias. + +- [This section](./README.md#getting-environment-aliases-to-target) explains how to get the environment alias. + +Go to your GitHub repository and enter the `Settings` section. + +- On the left side menu, find the `Security` section and click on `Actions`. +- Click on the tab `Variables`. +- Click on `New repository variable`. + - Call the variable `TARGET_ENVIRONMENT_ALIAS`. + - Use the environment alias as a value. +- Click on `Add variable`. + +You can use any of the available aliases, but to get similar functionality as before, select the environment described as `Leftmost mainline`. diff --git a/umbraco-cloud/set-up/project-settings/umbraco-cicd/v1-umbraco-cloud-api.md b/umbraco-cloud/set-up/project-settings/umbraco-cicd/v1-umbraco-cloud-api.md new file mode 100644 index 00000000000..0c43dc80961 --- /dev/null +++ b/umbraco-cloud/set-up/project-settings/umbraco-cicd/v1-umbraco-cloud-api.md @@ -0,0 +1,364 @@ +--- +hidden: true +--- + +# Cloud API For CI/CD Flow + +The Umbraco Cloud API serves as a publicly accessible endpoint that customers can utilize to execute relevant tasks. + +While its initial focus is on automating and managing deployments in Umbraco Cloud projects via the "Umbraco CI/CD Flow," future enhancements will broaden its capabilities to encompass a wider range of activities and options for Umbraco Cloud users. + +For the scope of this discussion, we will concentrate solely on the endpoints associated with interactions within the Umbraco CI/CD Flow. + +## Getting started + +To integrate Umbraco Cloud into your CI/CD pipeline, you'll need to make API calls to the following endpoint `https://api.cloud.umbraco.com`: + +* `/$projectId/deployments` +* `/$projectId/deployments/$deploymentId` +* `/$projectId/deployments/$deploymentId/package` +* `/$projectId/deployments/$latestCompletedDeploymentId/diff` + +You will find relevant examples using `Curl` and `Powershell` in the sections below. + +### How to enable CI/CD Integrator in the Umbraco Cloud Portal + +To authenticate with the Umbraco Cloud API, you'll need your Project ID and API Key. These credentials can be found under **Configuration > Advanced** in the Umbraco Cloud portal. + +![Umbraco CI/CD Flow](../../images/Advanced-Section.png) + +The two elements to be used for the authentication are: + +* **Cloud Project ID**: The ID of your Umbraco project. +* **CI/CD API Key**: Your unique identifier. + +By including the API key header in your HTTP requests, you ensure secure access to your Umbraco Cloud project's resources. + +For enhanced security, it's crucial to store the provided API key in a secure location. Options include a variable group in Azure DevOps or using the Secrets feature in GitHub Actions. It's important to note that each API key is tightly coupled with a specific Umbraco Cloud project and can only be used for deployments related to that project. + +### How to authenticate your requests + +To authenticate your requests, include the API key in a custom HTTP header named API key. + +_PowerShell_ is a command-line shell and scripting language commonly used for automating tasks and managing configurations. It offers a versatile set of cmdlets that allow you to interact with APIs, manipulate files, and much more. Within the context of the Umbraco Cloud API, PowerShell can be employed to authenticate your requests by incorporating your unique API key. + +_Curl_ (Client URL) is a command-line tool commonly used for making HTTP requests. It's a versatile utility that allows you to interact with APIs, download files, and more. In the context of Umbraco Cloud API, curl can be used to authenticate your requests by including your unique API key. + +To authenticate your API requests using curl, you'll need to include your API key in a custom HTTP header named Umbraco-Cloud-Api-Key. Here's how typical Powershell and curl commands would look for this purpose: + +{% tabs %} +{% tab title="Powershell" %} +```powershell +Invoke-RestMethod -Uri $url -Headers @{ "Umbraco-Cloud-Api-Key" = $apiKey } -Method Get +``` +{% endtab %} + +{% tab title="Curl" %} +``` +curl -s -X GET $url -H "Umbraco-Cloud-Api-Key: $apiKey" +``` +{% endtab %} +{% endtabs %} + +## How to make a deployment to Umbraco Cloud using the Umbraco CI/CD API + +### Create the deployment + +The Create Deployment endpoint initiates a new deployment and returns a unique `deploymentId`. This call serves as the initial step in the deployment process. It requires a `projectId` specified in the URL path and a commit message included in the request body. Essentially, this establishes the metadata necessary for initiating the deployment process. If a deployment is already underway, initiating a new one will be possible but should be avoided. + +To create a deployment, you'll need to make an HTTP POST request. The request body should contain a simple JSON object with the commit message: + +```json +{ + "commitMessage": "New dashboard for customer sales numbers" +} +``` + +In Powershell, the command to initiate a new deployment would be as follows + +```powershell +... +$url = "https://api.cloud.umbraco.com/v1/projects/$projectId/deployments" +$headers = @{ + "Umbraco-Cloud-Api-Key" = $apiKey + "Content-Type" = "application/json" +} + +$body = @{ + commitMessage = $commitMessage +} | ConvertTo-Json + +Invoke-RestMethod -Uri $url -Headers $headers -Method Post -Body $body +``` + +In curl, the command to initiate a new deployment would be as follows + +```sh +... +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments" + +curl -s -X POST $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: application/json" \ + -d "{\"commitMessage\":\"$commitMessage\"}" +``` + +Part of the returned response will be the actual `deploymentId`. The response from the API should be an HTTP 201 Created response including a `deploymentId`. This ID can be stored in the pipeline variables so it can be used in later steps. + +```json +{ + "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", + "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", + "projectAlias": "", + "deploymentState": "Created", + "updateMessage": "", + "errorMessage": "", + "created": "2023-05-02T07:16:46.4183912", + "lastModified": "2023-05-02T07:16:48.8544387", + "completed": null +} +``` + +### Upload zip source file + +To deploy content to the Umbraco Cloud repository, you need to perform an HTTP POST request to the Umbraco Cloud API. The deployment content should be packaged as a ZIP file, which must mirror the expected structure of the Umbraco Cloud repository. This ZIP file should include all relevant files such as project and solution files, and compiled frontend code. If your setup includes a frontend project with custom elements, the build artifacts from that project should also be included in the ZIP file, and placed in the appropriate directory within the repository structure. + +The HTTP POST request should be made using the `multipart/form-data` content type. The request URL should incorporate both the `projectId` and `deploymentId` obtained from the previous step in the API path. + +The ZIP file must be structured the same way as described in the `Readme.md` included in all cloud projects starting from Umbraco 9. This also means if you need to change the name and/or structure of the project, you should follow the guide in the same Readme. + +By adhering to these guidelines, you ensure that the uploaded content is an exact match with what is expected in the Umbraco Cloud repository, facilitating a seamless deployment process. + +The purpose of packaging your content into a ZIP file is to replace the existing content in the Umbraco Cloud repository upon unpackaging. This ensures that the repository is updated with the latest version of your project files. + +Make sure your ZIP archive does not contain .git folder. If you're using the `.zipignore` file, you can add the following line `.git/*` to exclude it. + +#### A note about .gitignore + +Umbraco Cloud environments are using git internally. This means you should be careful about the .gitignore file you add to the package. If you have “git ignored” build js assets locally, you need to handle this so that this is not being ignored in the cloud repository. + +**Note:** If the `.gitignore` file within the ZIP package does not exclude bin/ and obj/ directories, these will also be committed to the Umbraco Cloud repository. + +**Best Practice:** If you have frontend assets your local repository's .gitignore file will most likely differ from the one intended for the Umbraco Cloud repository, it's advisable to create a separate .cloud\_gitignore file. Include this file in the ZIP package and rename it to .gitignore before packaging. This ensures that only the necessary files and directories are uploaded and finally committed to the Umbraco Cloud repository. + +In curl uploading the source file will be: + +```sh +... +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId/package" + +curl -s -X POST $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: multipart/form-data" \ + --form "file=@$file" +``` + +The response of this call will be the same deployment object (in JSON) as when creating a new deployment, but the deploymentState should now be 'Pending': + +```json +{ + "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", + "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", + "projectAlias": "cicd-demo-site", + "deploymentState": "Pending", + "updateMessage":"Project information set\nDeployment pending\nDownloadUri set", + "errorMessage": "", + "created": "2023-05-02T07:16:46.4183912", + "lastModified": "2023-05-02T07:17:48.8544387", + "completed": null +} +``` + +### Start Deployment + +After the source file has been uploaded the deployment can be started. This will queue the deployment in the Umbraco Cloud services which will start the deployment as soon as possible. Starting the deployment is an HTTP PATCH request to the Umbraco Cloud API. `projectId` and the `deploymentId` from the previous step must be included in the path, and the deployment state set to 'Queued' in the request body. + +In curl starting a deployment will be: + +```sh +... +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId" + +curl -s -X PATCH $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: application/json" \ + -d "{\"deploymentState\": \"Queued\"}" +``` + +The response of this call will be the same deployment object (in JSON) as when creating a new deployment, but the deploymentState should now be 'Queued': + +```json +{ + "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", + "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", + "projectAlias": "cicd-demo-site", + "deploymentState": "Queued", + "updateMessage": "Project information set\nDeployment pending\nDownloadUri set\nDeployment queued", + "errorMessage": "", + "created": "2023-05-02T07:16:46.4183912", + "lastModified": "2023-05-02T07:18:48.8544387", + "completed": null +} +``` + +### Get Deployment status + +To monitor the status of a deployment—whether it's completed, successful, or otherwise — you can periodically query the 'Get Deployment Status' API. This API endpoint is an HTTP GET request to the Umbraco Cloud API, and it requires both the `projectId` and the `deploymentId` obtained from previous steps to be included in the path. + +Deployments in Umbraco services can take varying amounts of time to complete. Therefore, it's advisable to poll this API at regular intervals to stay updated on the deployment's current state. For example, in a simple project, you might choose to poll the API every 15 seconds for a duration of 15 minutes. These figures are just a starting point; the optimal polling frequency and duration may differ for your specific pipeline. Based on initial experience, a 15-minute window generally suffices, but we welcome your feedback to fine-tune these parameters. + +Using a curl command, polling for the deployment status would look like this: + +```sh +... +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$deploymentId" + +# Define a function to call API and check the status +function call_api { + response=$(curl -s -X GET $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: application/json") + echo "$response" + status=$(echo $response | jq -r '.deploymentState') +} + +# Call API and check status +call_api +while [[ $status == "Pending" || $status == "InProgress" || $status == "Queued" ]]; do + echo "Status is $status, waiting 15 seconds..." + sleep 15 + call_api + if [[ $SECONDS -gt 900 ]]; then + echo "Timeout reached, exiting loop." + break + fi +done + +# Check final status +if [[ $status == "Completed" ]]; then + echo "Deployment completed successfully." +elif [[ $status == "Failed" ]]; then + echo "Deployment failed." + exit 1 +else + echo "Unexpected status: $status" + exit 1 +fi + +``` + +The response from this API call will return the same deployment object in JSON format as you would receive from other API interactions. Ultimately, the `deploymentState` field will indicate either 'Completed' or 'Failed'. Should the deployment fail, the 'ErrorMessage' field will provide additional details regarding the issue. + +```json +{ + "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", + "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", + "projectAlias": "cicd-demo-site", + "deploymentState": "Completed", + "updateMessage":"Project information set\nDeployment pending\nDownloadUri set\nDeployment queued\nDeployment triggered\nDeployment started\nCheck blocking markers\nCreate updating marker\nGit Clone\nDownload update\nExtract Update\nChecking versions\nDeleting repository files\nCopying files to repository\nNuGet Restore\nDotnet Build\nGit Stage\nGit Commit\nGit Tag\nGit Push\nDelete updating marker\nDeployment successful", + "errorMessage": "", + "created": "2023-05-02T07:16:46.4183912", + "lastModified": "2023-05-02T07:20:48.8544387", + "completed": "2023-05-02T07:20:49.8544387" +} +``` + +### Get Deployments + +The endpoint lets you retrieve a list of completed deployments. It can only list deployments that has been run through the api. + +The API allows you to filter and limit the number of returned deployments using query parameters: + +* _Skip_ : optional, zero or positive integer +* _Take_ : optional, zero or positive integer +* _Includenulldeployments_ : optional, boolean, defaults to true + +The "skip" and "take" parameters, while optional, are always required to be used together. + +With `includenulldeployments` set to true, you will get all completed deployments, including those that did not create any new changes in the cloud repository. + +To fetch the list of deployments using a curl command, the syntax would be as follows: + +```sh +... +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments?skip=0&take=1&includenulldeployments=false" + +response=$(curl -s -X GET $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: application/json") +latestDeploymentId=$(echo $response | jq -r '.deployments[0].deploymentId') + +``` + +The response from this API call will return an object containing a list of deployment objects. The deployment-objects are consistent with the structure used in other API responses. Deployments are listed in descending order based on their creation timestamp. + +```json +{ + "projectId": "abcdef12-cef8-4e92-8887-ceb123456789", + "deployments": + [ + { + "deploymentId": "bc0ebd6f-cef8-4e92-8887-ceb862a83bf0", + "projectId" : "abcdef12-cef8-4e92-8887-ceb123456789", + "projectAlias": "cicd-demo-site", + "deploymentState": "Completed", + "updateMessage": "...", + "errorMessage": "", + "created": "2023-05-02T07:16:46.4183912", + "lastModified": "2023-05-02T07:18:48.8544387", + "completed": "2023-05-02T07:22:48.8544387" + } + ] +} +``` + +### Get Deployment diff + +Sometimes updates are done directly on the Umbraco Cloud repository. We encourage you to not do any actual work there, but auto-upgrades and environment changes will affect the umbraco-cloud-git-repos. To keep track of such changes, you can use the 'Get Deployment Diff' API. This API endpoint will provide you with a git-patch file detailing the changes between a specific deployment and the current state of the repository. To make this API call, you'll need to include both the `projectId` and the `deploymentId` of the deployment you want to check for differences against. This is a standard HTTP GET request. + +Using a curl command, fetching the potential differences would look like this: + +```sh +url="https://api.cloud.umbraco.com/v1/projects/$projectId/deployments/$latestCompletedDeploymentId/diff" +downloadFolder="tmp" +mkdir -p $downloadFolder # ensure folder exists + +responseCode=$(curl -s -w "%{http_code}" -L -o "$downloadFolder/git-patch.diff" -X GET $url \ + -H "Umbraco-Cloud-Api-Key: $apiKey" \ + -H "Content-Type: application/json") + +if [[ 10#$responseCode -eq 204 ]]; then # Http 204 No Content means that there are no changes + echo "No changes" + rm -fr $downloadFolder/git-patch.diff +elif [[ 10#$responseCode -eq 200 ]]; then # Http 200 downloads the file and set a few variables for pipeline + echo "Changes - check file - $downloadFolder/git-patch.diff" +else + echo "Unexpected status: $responseCode" + exit 1 +fi + +``` + +The API response will vary based on whether or not there are changes to report. If no changes are detected, you'll receive an HTTP 204 No Content status. On the other hand, if there are changes, the API will return an HTTP 200 OK status along with a git-patch file as the content. This git-patch file can then be applied to your local repository to sync it with the changes. + +### Possible errors + +When interacting with the Umbraco Cloud API, you may encounter various HTTP status codes that indicate the success or failure of your API request. Below is a table summarizing the possible status codes, their corresponding errors, and basic root causes to guide your troubleshooting: + +| Status Code | Error | Basic Root Cause | +| ----------- | ------------------- | ----------------------------------------------------------------------------------- | +| 400 | BadRequest | Check the requested path, supplied headers and query-parameters | +| 401 | Unauthorized | Check the Project Id and Api Key | +| 404 | NotFound | Usually related to the supplied deploymentId in path not being found | +| 409 | Conflict | The state of the referenced deployment is not ready for the work you are requesting | +| 500 | InternalServerError | InternalServerError | + +Most errors have a response body that corresponds to this JSON, and the “detail” field will have a more complete error message. + +``` +{ + “title”: string, + “status”: number, + “detail”: string, +} +```