After the build is complete, Pipelines creates a “build artifact” consisting of the contents of the SOURCE_DIR and commits the artifact to your Cloud Platform repository in a build branch named pipelines-build-[BRANCHNAME] by default.
Pipelines commits build artifacts automatically and does not log the results of the commit. However, the pipelines start command does display the path of the build branch in the repository.
Storing the build artifact in your Cloud Platform repository provides the following advantages over alternatives such as creating a tarball:
git diff.After you complete a build, you can deploy the resulting build artifact in any Cloud Platform environment. You can do this by selecting the build branch for deployment by using the Cloud Platform user interface or Cloud API.
After you set the deployed branch of an environment to a build branch, each build artifact committed to that branch is deployed immediately, without requiring any intervention. For example, if you build the master branch, and your Cloud Platform development environment is set to the pipelines-build-master branch, the build artifact is deployed immediately to that development environment when the pipeline job completes successfully.
pipelines-build-[branch_name] or pipelines-build-[tag_name].To write a shell script for deploying artifacts, create a file named deploy-artifact.sh, and place it in the root directory of the repository. Ensure that the file contains the following:
#!/bin/bash
set -e
# This is a script to deploy NodeJs artifact
# Note: This script doesn't handle the token expiry or any API exceptions/errors.
# A function to end script unsuccessfuly
err() {
echo "Failed to deploy the artifact, check task log for more details at $PIPELINE_JOB_URL"
exit 1
}
if [[ -z "${TARGET_ENV_NAME}" ]]
then
echo "Target environment name is not defined, make sure that TARGET_ENV_NAME environment variable is set"
err
fi
if [[ -z "${PIPELINE_ARTIFACT_START_LOG}" ]]
then
echo "Pipeline artifact start log is not defined, make sure that PIPELINE_ARTIFACT_START_LOG environment variable is set"
err
fi
# Get Cloud Authentication token. For more details: https://docs.acquia.com/acquia-cloud/develop/api/auth/
max_retries=3
attempt=1
delay=5
TOKEN=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for token generation:"
response=$(curl -sS -w "\n%{http_code}" -X POST -u "${CLOUD_API_KEY}:${CLOUD_API_SECRET}" -d "grant_type=client_credentials" https://accounts.acquia.com/api/auth/oauth/token)
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving token:"
TOKEN=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
echo "Token retrieved from response"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TOKEN" ]]; then
echo "Failed to obtain token after $attempt attempts."
exit 1
fi
# Get target environment Id.
attempt=1
TARGET_ENV_ID=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for TARGET_ENV_ID:"
response=$(curl -sS -w "\n%{http_code}" -X GET "https://cloud.acquia.com/api/applications/$PIPELINE_APPLICATION_ID/environments" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving TARGET_ENV_ID:"
TARGET_ENV_ID=$(echo "$response_body" | python3 -c "import sys, json; envs=json.load(sys.stdin)['_embedded']['items']; print([x for x in envs if x['name'] == '$TARGET_ENV_NAME'][0]['id'])")
echo "TARGET_ENV_ID is $TARGET_ENV_ID"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TARGET_ENV_ID" ]]; then
echo "Failed to obtain TARGET_ENV_ID after $attempt attempts."
exit 1
fi
# Get artifact id from pipeline-artifact start log.
ARTIFACT_ID=$(grep artifactId $PIPELINE_ARTIFACT_START_LOG | cut -d ' ' -f3)
echo ARTIFACT_ID is $ARTIFACT_ID
# Put artifact id into pipeline metadata, so you can get it later if necessary.
pipelines_metadata artifact_id $ARTIFACT_ID
# Deploy artifact to target envronment. Use the notification url returned to get the tasks's status.
# For more details: http://cloudapi-docs.acquia.com/#/Environments/postDeployArtifact
attempt=1
NOTIFICATION_LINK=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X POST -d "{\"artifact_id\":\"$ARTIFACT_ID\"}" "https://cloud.acquia.com/api/environments/$TARGET_ENV_ID/artifacts/actions/switch" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving NOTIFICATION_LINK:"
NOTIFICATION_LINK=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['_links']['notification']['href'])")
echo "NOTIFICATION_LINK is $NOTIFICATION_LINK"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$NOTIFICATION_LINK" ]]; then
echo "Failed to obtain NOTIFICATION_LINK after $max_retries attempts."
exit 1
fi
# Poll NOTIFICATION_LINK to know the task status, the status will be 'in-progress' until the task is finished. For more details: https://cloudapi-docs.acquia.com/#/Notifications/getNotificationByUuid
#DEPLOY_STATUS='in-progress'
attempt=1
DEPLOY_STATUS=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Checking deployment status from NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X GET "$NOTIFICATION_LINK" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
DEPLOY_STATUS=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['status'])")
echo "Current deployment status: $DEPLOY_STATUS"
# Exit the loop if the deployment status is fetched successfully
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$DEPLOY_STATUS" ]]; then
echo "Failed to retrieve DEPLOY_STATUS after $max_retries attempts."
exit 1
fi
echo "Waiting for the deployment to be finished, current status: $DEPLOY_STATUS."
# Tracking deployment status
while [ "$DEPLOY_STATUS" = 'in-progress' ]; do
sleep 60
echo "Tracking DEPLOY_STATUS ..."
attempt=1
TOKEN=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for token re-generation:"
response=$(curl -sS -w "\n%{http_code}" -X POST -u "${CLOUD_API_KEY}:${CLOUD_API_SECRET}" -d "grant_type=client_credentials" https://accounts.acquia.com/api/auth/oauth/token)
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving token:"
TOKEN=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
echo "Token retrieved from response"
echo "New TOKEN generated";
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TOKEN" ]]; then
echo "Failed to obtain token after $attempt attempts."
exit 1
fi
# Poll NOTIFICATION_LINK to know the task status
attempt=1
DEPLOY_STATUS=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Checking deployment status from NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X GET "$NOTIFICATION_LINK" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
DEPLOY_STATUS=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['status'])")
echo "Current deployment status: $DEPLOY_STATUS"
# Exit the loop if the deployment status is fetched successfully
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$DEPLOY_STATUS" ]]; then
echo "Failed to retrieve DEPLOY_STATUS after $max_retries attempts."
exit 1
fi
echo "Waiting for the deployment to be finished, current status: $DEPLOY_STATUS."
done
echo $DEPLOY_STATUS
# Exit with 1 if the final status is 'failed'. Do nothing if the final status is 'completed' which mean the deployment is successful.
if [ "$DEPLOY_STATUS" = 'failed' ]
then
err
fi
Node.js application support in Cloud Platform uses the Cloud Platform pipelines functionality to build an artifact that you can then deploy to your environment.
Each artifact has a name, which enables you to select a specific artifact by that name in the deployment phase. When you deploy, the most recently built artifact will be at the top of the list. The default naming convention for node artifacts is as follows:
[git branch]@[commit hash]This can cause issues, as commits can be amended. This can result in two artifacts with the same name but with different comments.
It is possible to set a default name for your artifact by adding configurations to your yaml file using the pipelines-artifact command and pipelines variables. To do this, complete the following steps:
Find the following line in the file:
- pipelines-artifact startEdit the line by adding the PIPELINE_VCS_PATH and PIPELINE_GIT_HEAD_REF options to your start command, similar to the following:
- PIPELINE_VCS_PATH=artifact PIPELINE_GIT_HEAD_REF=example pipelines-artifact startUsing this example, your artifact name will become artifact@example rather than branch@commit.
If this content did not answer your questions, try searching or contacting our support team for further assistance.
After you complete a build, you can deploy the resulting build artifact in any Cloud Platform environment. You can do this by selecting the build branch for deployment by using the Cloud Platform user interface or Cloud API.
After you set the deployed branch of an environment to a build branch, each build artifact committed to that branch is deployed immediately, without requiring any intervention. For example, if you build the master branch, and your Cloud Platform development environment is set to the pipelines-build-master branch, the build artifact is deployed immediately to that development environment when the pipeline job completes successfully.
pipelines-build-[branch_name] or pipelines-build-[tag_name].To write a shell script for deploying artifacts, create a file named deploy-artifact.sh, and place it in the root directory of the repository. Ensure that the file contains the following:
#!/bin/bash
set -e
# This is a script to deploy NodeJs artifact
# Note: This script doesn't handle the token expiry or any API exceptions/errors.
# A function to end script unsuccessfuly
err() {
echo "Failed to deploy the artifact, check task log for more details at $PIPELINE_JOB_URL"
exit 1
}
if [[ -z "${TARGET_ENV_NAME}" ]]
then
echo "Target environment name is not defined, make sure that TARGET_ENV_NAME environment variable is set"
err
fi
if [[ -z "${PIPELINE_ARTIFACT_START_LOG}" ]]
then
echo "Pipeline artifact start log is not defined, make sure that PIPELINE_ARTIFACT_START_LOG environment variable is set"
err
fi
# Get Cloud Authentication token. For more details: https://docs.acquia.com/acquia-cloud/develop/api/auth/
max_retries=3
attempt=1
delay=5
TOKEN=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for token generation:"
response=$(curl -sS -w "\n%{http_code}" -X POST -u "${CLOUD_API_KEY}:${CLOUD_API_SECRET}" -d "grant_type=client_credentials" https://accounts.acquia.com/api/auth/oauth/token)
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving token:"
TOKEN=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
echo "Token retrieved from response"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TOKEN" ]]; then
echo "Failed to obtain token after $attempt attempts."
exit 1
fi
# Get target environment Id.
attempt=1
TARGET_ENV_ID=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for TARGET_ENV_ID:"
response=$(curl -sS -w "\n%{http_code}" -X GET "https://cloud.acquia.com/api/applications/$PIPELINE_APPLICATION_ID/environments" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving TARGET_ENV_ID:"
TARGET_ENV_ID=$(echo "$response_body" | python3 -c "import sys, json; envs=json.load(sys.stdin)['_embedded']['items']; print([x for x in envs if x['name'] == '$TARGET_ENV_NAME'][0]['id'])")
echo "TARGET_ENV_ID is $TARGET_ENV_ID"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TARGET_ENV_ID" ]]; then
echo "Failed to obtain TARGET_ENV_ID after $attempt attempts."
exit 1
fi
# Get artifact id from pipeline-artifact start log.
ARTIFACT_ID=$(grep artifactId $PIPELINE_ARTIFACT_START_LOG | cut -d ' ' -f3)
echo ARTIFACT_ID is $ARTIFACT_ID
# Put artifact id into pipeline metadata, so you can get it later if necessary.
pipelines_metadata artifact_id $ARTIFACT_ID
# Deploy artifact to target envronment. Use the notification url returned to get the tasks's status.
# For more details: http://cloudapi-docs.acquia.com/#/Environments/postDeployArtifact
attempt=1
NOTIFICATION_LINK=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X POST -d "{\"artifact_id\":\"$ARTIFACT_ID\"}" "https://cloud.acquia.com/api/environments/$TARGET_ENV_ID/artifacts/actions/switch" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving NOTIFICATION_LINK:"
NOTIFICATION_LINK=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['_links']['notification']['href'])")
echo "NOTIFICATION_LINK is $NOTIFICATION_LINK"
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$NOTIFICATION_LINK" ]]; then
echo "Failed to obtain NOTIFICATION_LINK after $max_retries attempts."
exit 1
fi
# Poll NOTIFICATION_LINK to know the task status, the status will be 'in-progress' until the task is finished. For more details: https://cloudapi-docs.acquia.com/#/Notifications/getNotificationByUuid
#DEPLOY_STATUS='in-progress'
attempt=1
DEPLOY_STATUS=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Checking deployment status from NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X GET "$NOTIFICATION_LINK" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
DEPLOY_STATUS=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['status'])")
echo "Current deployment status: $DEPLOY_STATUS"
# Exit the loop if the deployment status is fetched successfully
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$DEPLOY_STATUS" ]]; then
echo "Failed to retrieve DEPLOY_STATUS after $max_retries attempts."
exit 1
fi
echo "Waiting for the deployment to be finished, current status: $DEPLOY_STATUS."
# Tracking deployment status
while [ "$DEPLOY_STATUS" = 'in-progress' ]; do
sleep 60
echo "Tracking DEPLOY_STATUS ..."
attempt=1
TOKEN=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Contacting endpoint for token re-generation:"
response=$(curl -sS -w "\n%{http_code}" -X POST -u "${CLOUD_API_KEY}:${CLOUD_API_SECRET}" -d "grant_type=client_credentials" https://accounts.acquia.com/api/auth/oauth/token)
http_code=$(echo "$response" | tail -n1)
echo "HTTP code: $http_code"
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "Retrieving token:"
TOKEN=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
echo "Token retrieved from response"
echo "New TOKEN generated";
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$TOKEN" ]]; then
echo "Failed to obtain token after $attempt attempts."
exit 1
fi
# Poll NOTIFICATION_LINK to know the task status
attempt=1
DEPLOY_STATUS=""
while [ $attempt -le $max_retries ]; do
echo "Attempt $attempt: Checking deployment status from NOTIFICATION_LINK:"
response=$(curl -sS -w "\n%{http_code}" -X GET "$NOTIFICATION_LINK" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}")
http_code=$(echo "$response" | tail -n1)
response_body=$(echo "$response" | sed '$d')
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
DEPLOY_STATUS=$(echo "$response_body" | python3 -c "import sys, json; print(json.load(sys.stdin)['status'])")
echo "Current deployment status: $DEPLOY_STATUS"
# Exit the loop if the deployment status is fetched successfully
break
else
echo "Request failed with HTTP $http_code. Response body: $response_body"
echo "Retrying in $delay seconds..."
sleep $delay
((attempt++))
fi
done
if [[ -z "$DEPLOY_STATUS" ]]; then
echo "Failed to retrieve DEPLOY_STATUS after $max_retries attempts."
exit 1
fi
echo "Waiting for the deployment to be finished, current status: $DEPLOY_STATUS."
done
echo $DEPLOY_STATUS
# Exit with 1 if the final status is 'failed'. Do nothing if the final status is 'completed' which mean the deployment is successful.
if [ "$DEPLOY_STATUS" = 'failed' ]
then
err
fi
Node.js application support in Cloud Platform uses the Cloud Platform pipelines functionality to build an artifact that you can then deploy to your environment.
Each artifact has a name, which enables you to select a specific artifact by that name in the deployment phase. When you deploy, the most recently built artifact will be at the top of the list. The default naming convention for node artifacts is as follows:
[git branch]@[commit hash]This can cause issues, as commits can be amended. This can result in two artifacts with the same name but with different comments.
It is possible to set a default name for your artifact by adding configurations to your yaml file using the pipelines-artifact command and pipelines variables. To do this, complete the following steps:
Find the following line in the file:
- pipelines-artifact startEdit the line by adding the PIPELINE_VCS_PATH and PIPELINE_GIT_HEAD_REF options to your start command, similar to the following:
- PIPELINE_VCS_PATH=artifact PIPELINE_GIT_HEAD_REF=example pipelines-artifact startUsing this example, your artifact name will become artifact@example rather than branch@commit.
If this content did not answer your questions, try searching or contacting our support team for further assistance.