diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml new file mode 100644 index 0000000..42b3bfa --- /dev/null +++ b/.github/workflows/default.yml @@ -0,0 +1,22 @@ +name: Default + +on: + push: + branches: [main] + tags-ignore: + - "*" + pull_request: + branches: [main] + + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + # - name: ShellCheck + # run: |- + # shellcheck -x entrypoint.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..028dc27 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + tags: + - "*" + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + # - name: ShellCheck + # run: |- + # shellcheck -x entrypoint.sh + + - name: Get CI_COMMIT_TAG + id: get_ci_commit_tag + run: echo CI_COMMIT_TAG=$(echo $GITHUB_REF | cut -d / -f 3) >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + platforms: linux/amd64,linux/arm64 + push: true + tags: | + echoeshq/gitlab-deployments-action:${{ steps.get_ci_commit_tag.outputs.CI_COMMIT_TAG }} + echoeshq/gitlab-deployments-action:latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d434b64 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.18 + +RUN apk add --no-cache --upgrade bash curl git jq + +RUN bash --version + +COPY helpers.sh /helpers.sh +COPY entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..c10bd21 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +This repository holds the main scripts used by https://gitlab.com/echoeshq/deployments-action. diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..01d46dd --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,139 @@ +#!/bin/bash -l + +# includes +. /helpers.sh + +cd "${CI_BUILDS_DIR}/${CI_PROJECT_PATH}" || exit 1 + +ECHOES_API_ENDPOINT="https://api.echoeshq.com/v1/signals/deployments" + +IFS=',' read -r -a deliverables <<< "${deliverables}" +IFS=',' read -r -a commits <<< "${commits}" +action_type=$(trim "${action-type}") +version=$(trim "${version}") + +deployment_id=$(trim "${deployment-id}") +status=$(trim "${status}") + +# Makes sure the API KEY is provided +if [ -z "${ECHOES_API_KEY}" ] +then + echo "No ECHOES_API_KEY provided! Please visit: https://docs.echoeshq.com/api-authentication#ZB9nc" + exit 1 +fi + +# Is the action used to post a deployment status? +if [ "${action_type}" == "post-status" ] +then + if [ -z "${status}" ] || [ -z "${deployment_id}" ] + then + echo "A status and a deployment ID are required. https://echoeshq.stoplight.io/docs/public-api/9vr19ihfs1pka-post-deployment-status" + exit 1 + fi + + response=$(curl --silent --show-error --fail-with-body --location "${ECHOES_API_ENDPOINT}/${deployment_id}/status" \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer '"${ECHOES_API_KEY}"'' \ + --data-raw '{ + "status": "'"${status}"'" + }') + + if [[ "${response}" != "" ]] + then + echo "${response}" + if [[ "$(echo "${response}" | jq .status)" -ge 400 ]] + then + exit 1 + fi + fi + + exit 0 +fi + +# If no deliverables provided look up for the CI_PROJECT_NAME. +# If the value could be empty. +if [ -z "${deliverables[0]}" ] || [ "$(arraylength "${deliverables[@]}")" -eq 0 ] +then + echo "No deliverables list provided, defaults to \$CI_PROJECT_NAME." + + if [ -z "${CI_PROJECT_NAME}" ] + then + echo "\$CI_PROJECT_NAME is missing. Please provide a deliverables list." + exit 1 + fi + + # Keep the project name as deliverable value + deliverables=( "${CI_PROJECT_NAME}" ) +fi + +# If no commits provided look up for tags. +# If no tags are found, look up for the commit SHA triggering the workflow (CI_COMMIT_SHA). +if [ -z "${commits[0]}" ] || [ "$(arraylength "${commits[@]}")" -eq 0 ] +then + # No commits list provided therefore look for tags + echo "Looking for commits via tags..." + + latestTags=$(git for-each-ref refs/tags --sort=-committerdate --format='%(refname:short)' --count=2 --merged) + + if [ -z "${latestTags}" ] + then + echo "No tags were found, therefore looking for \$CI_COMMIT_SHA" + if [ -z "${CI_COMMIT_SHA}" ] + then + echo "No tags were found, nor \$CI_COMMIT_SHA therefore no deployment can be submitted." + echo "Please provide a commits list or make sure to have used the actions/checkout beforehand." + exit 1 + else + commits=("${CI_COMMIT_SHA}") + fi + else + mapfile -t tags <<< "$latestTags" + numberOfTags=$(arraylength "${tags[@]}") + + if [ "${numberOfTags}" -gt 0 ] + then + if [ "${numberOfTags}" -lt 2 ] + then + tag=${tags[0]} + + echo "Extract commits from ${tag}" + + mapfile -t commits < <(git log --pretty=format:%H "${tag}") + else + tag=${tags[0]} + prev_tag=${tags[1]} + + echo "Extract commits from ${prev_tag} to ${tag}" + + mapfile -t commits < <(git log --pretty=format:%H "${prev_tag}".."${tag}") + fi + fi + fi +fi + +deliverablesJSON=$(jq --compact-output --null-input '$ARGS.positional' --args "${deliverables[@]}") +commitsJSON=$(jq --compact-output --null-input '$ARGS.positional' --args "${commits[@]}") + +response=$(curl --silent --show-error --fail-with-body --location "${ECHOES_API_ENDPOINT}" \ +--header 'Accept: application/json' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer '"${ECHOES_API_KEY}"'' \ +--data-raw '{ + "version": "'"${version}"'", + "commits": '"${commitsJSON}"', + "deliverables": '"${deliverablesJSON}"' +}') + +# Display response body +echo "${response}" + +if [[ "${response}" != "" ]] +then + if [[ "$(echo "${response}" | jq .status)" -ge 400 ]] + then + exit 1 + fi + + deployment_id=$(echo "${response}" | jq .id) + echo "deployment_id=${deployment_id}" >> build.env +fi diff --git a/helpers.sh b/helpers.sh new file mode 100755 index 0000000..e9b43c6 --- /dev/null +++ b/helpers.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +function trim() { + echo "${1}" | xargs +} + +function arraylength() { + echo "$#" +}