diff --git a/Dockerfile b/Dockerfile index 4e86601..acd987e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,8 @@ ARG CLI_TIMESTAMP="20200812001454" RUN apt-get update && apt-get install -y --no-install-recommends \ jq \ u2f-host \ + git \ + openssh-client \ && rm -rf /var/lib/apt/lists/* WORKDIR /tmp/aptible-cli diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b9e1568 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +TAG?=$(shell git log --format="%H" -n 1) +PLATFORM?=linux/amd64 + +image: + docker buildx build \ + --push \ + --platform $(PLATFORM) \ + -t quay.io/aptible/aptible-deploy-action:$(TAG) \ + . +.PHONY: image diff --git a/README.md b/README.md index 0b59340..8aef445 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,137 @@ -# Github Action to deploy onto Aptible Deploy +This action helps you deploy Apps to [Aptible](https://www.aptible.com/). -This action deploys a Docker image to [Aptible](https://www.aptible.com/). To use this image, you should use another workflow step to publish your image to a Docker image registry (for example [Docker's](https://github.com/marketplace/actions/build-and-push-docker-images)). +There are two deployment strategies, both are supported in this action: -If you are using a private registry, you can optionally setup [Private Registry Authentication](https://deploy-docs.aptible.com/docs/private-registry-authentication) once ahead of time using the [Aptible CLI](https://deploy-docs.aptible.com/docs/cli). Otherwise, you can pass the credentials directly via the action. +- [Git Push](#git-push-deploy) +- [Direct Docker Image](#direct-docker-image-deploy) -```bash -aptible config:set \ - --app "$APP_HANDLE" \ - "APTIBLE_PRIVATE_REGISTRY_USERNAME=$USERNAME" - "APTIBLE_PRIVATE_REGISTRY_PASSWORD=$PASSWORD" +If you are just getting started at Aptible, the easiest deployment strategy is +[Git Push](#git-push-deploy). + +# Git Push Deploy + +[Read the docs on this strategy](https://www.aptible.com/docs/dockerfile-deploy). + +## Inputs + +The following inputs can be used as `step.with` keys + +### Required input + +- `type` - set to `git` +- `username` - Aptible email login +- `password` - Aptible password login +- `app` - [Aptible App](https://www.aptible.com/docs/apps) handle +- `environment` - + [Aptible Environment](https://www.aptible.com/docs/environments) handle the + App is hosted within + +### Optional input + +- `config_variables` - [configuration variables to set](https://www.aptible.com/docs/set-configuration-variables) + +> [!IMPORTANT]\ +> We do **not** recommend setting `config_variables` inside our github action +> because those variables only need to be set once within Aptible for them to +> persist across deployments. +> [Learn more](https://www.aptible.com/docs/set-configuration-variables). + +## Example using Git Push + +Assumes you have set +[secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) +(recommended). + +```yaml +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Deploy to Aptible + uses: aptible/aptible-deploy-action@v2 + with: + type: git + app: + environment: + username: ${{ secrets.APTIBLE_USERNAME }} + password: ${{ secrets.APTIBLE_PASSWORD }} ``` +# Direct Docker Image Deploy + +[Read the docs on this strategy](https://www.aptible.com/docs/direct-docker-image-deploy-example). + +To use this image, you should use another workflow step to publish your image to +a Docker image registry (for example +[Docker's](https://github.com/marketplace/actions/build-and-push-docker-images)). + +If you are using a private registry, you can optionally setup +[Private Registry Authentication](https://www.aptible.com/docs/direct-docker-image-deploy#private-registry-authentication) +once ahead of time using the +[Aptible CLI](https://deploy-docs.aptible.com/docs/cli). Otherwise, you can pass +the credentials directly via the action. + ## Inputs The following inputs can be used as `step.with` keys ### Required input -- `username` - passed to `aptible` CLI -- `password` - passed to `aptible` CLI -- `environment` - specifies App to be deployed -- `app` - specifies App to be deployed -- `docker_img` - the name of the image you’d like to deploy, including its repository and tag +- `type` - set to `docker` +- `username` - Aptible email login +- `password` - Aptible password login +- `environment` - + [Aptible Environment](https://www.aptible.com/docs/environments) handle the + App is hosted within +- `app` - [Aptible App](https://www.aptible.com/docs/apps) handle +- `docker_img` - the name of the image you'd like to deploy, including its + repository and tag ### Optional input -- `private_registry_username` - the username for the private registry to pull a docker image from -- `private_registry_password` - the password for the private registry to pull a docker image from -- `config_variables` - a space separated list of key=value pairs to set as config variables on the app during deployment +- `private_registry_username` - the username for the private image registry +- `private_registry_password` - the password for the private image registry +- `config_variables` - JSON string containing the + [configuration variables to set](https://www.aptible.com/docs/set-configuration-variables) + +> [!IMPORTANT]\ +> We do **not** recommend setting `config_variables` inside our github action +> because those variables only need to be set once within Aptible for them to +> persist across deployments. +> [Learn more](https://www.aptible.com/docs/set-configuration-variables). ## Outputs - `status` - success/failure of the deploy -## Example github actions usage +## Example using Direct Docker Image Deploy -Assumes you have set [secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) (recommended). +Assumes you have set +[secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) +(recommended). ```yaml jobs: deploy: runs-on: ubuntu-latest - - - name: Deploy to Aptible - uses: aptible/aptible-deploy-action@v1 - with: - username: ${{ secrets.APTIBLE_USERNAME }} - password: ${{ secrets.APTIBLE_PASSWORD }} - environment: - app: - docker_img: - private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }} - private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }} - config_variables: KEY1=value1 KEY2=value2 + steps: + - name: Deploy to Aptible + uses: aptible/aptible-deploy-action@v2 + with: + type: docker + app: + environment: + username: ${{ secrets.APTIBLE_USERNAME }} + password: ${{ secrets.APTIBLE_PASSWORD }} + docker_img: + private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }} + private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }} + config_variables: DEBUG=app:* FORCE_SSL=true ``` -## Example with Container Build and Docker Hub +## Example using Container Build and Docker Hub ```yaml - env: IMAGE_NAME: user/app:latest APTIBLE_ENVIRONMENT: "my_environment" @@ -68,38 +141,39 @@ env: jobs: deploy: runs-on: ubuntu-latest - - # Allow multi platform builds. - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - # Allow use of secrets and other advanced docker features. - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - # Log into Docker Hub - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - # Build image using default dockerfile. - - name: Build and push - uses: docker/build-push-action@v3 - with: - push: true - tags: ${{ env.IMAGE_NAME }} - - - name: Deploy to Aptible - uses: aptible/aptible-deploy-action@v1 - with: - username: ${{ secrets.APTIBLE_USERNAME }} - password: ${{ secrets.APTIBLE_PASSWORD }} - environment: ${{ env.APTIBLE_ENVIRONMENT }} - app: ${{ env.APTIBLE_APP }} - docker_img: ${{ env.IMAGE_NAME }} - private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }} - private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }} - config_variables: RELEASE_SHA=${{ github.sha }} + steps: + # Allow multi platform builds. + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + # Allow use of secrets and other advanced docker features. + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + # Log into Docker Hub + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Build image using default dockerfile. + - name: Build and push + uses: docker/build-push-action@v3 + with: + push: true + tags: ${{ env.IMAGE_NAME }} + + - name: Deploy to Aptible + uses: aptible/aptible-deploy-action@v2 + with: + type: docker + app: ${{ env.APTIBLE_APP }} + environment: ${{ env.APTIBLE_ENVIRONMENT }} + username: ${{ secrets.APTIBLE_USERNAME }} + password: ${{ secrets.APTIBLE_PASSWORD }} + docker_img: ${{ env.IMAGE_NAME }} + private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }} + private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }} + config_variables: RELEASE_SHA=${{ github.sha }} ``` diff --git a/action.yml b/action.yml index aa31a27..dec515b 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,5 @@ -# action.yml name: 'Deploy to Aptible' -description: 'Deploy an app from a Dockerfile to Aptible' +description: 'Deploy an App to Aptible' inputs: username: description: 'Aptible username' @@ -8,15 +7,23 @@ inputs: password: description: 'Aptible password' required: True - environment: - description: 'Aptible environment' + environment: + description: 'Aptible environment handle' required: True - app: + app: description: 'App handle' required: True - docker_img: - description: 'Docker image' + type: + description: 'Deploy strategy "git" or "docker"' required: True + default: 'docker' + git_remote: + description: 'Aptible git remote domain' + required: False + default: primetime.aptible.com + docker_img: + description: 'Docker image' + required: False private_registry_username: description: 'Private Registry Username' required: False @@ -31,4 +38,5 @@ outputs: description: "The Success/Failure of the action" runs: using: 'docker' - image: 'Dockerfile' + # image: 'Dockerfile' + image: docker://quay.io/aptible/aptible-deploy-action:v2 diff --git a/entrypoint.sh b/entrypoint.sh index 0019ec5..5e4b432 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -21,11 +21,6 @@ if [ -z "$INPUT_APP" ]; then exit 1 fi -if [ -z "$INPUT_DOCKER_IMG" ]; then - echo "Aborting: docker_img is not set" - exit 1 -fi - aptible login \ --email "$INPUT_USERNAME" \ --password "$INPUT_PASSWORD" @@ -35,9 +30,40 @@ if ! APTIBLE_OUTPUT_FORMAT=json aptible apps | jq -e ".[] | select(.handle == \" exit 1 fi -aptible deploy --environment "$INPUT_ENVIRONMENT" \ - --app "$INPUT_APP" \ - --docker-image "$INPUT_DOCKER_IMG" \ - --private-registry-username "$INPUT_PRIVATE_REGISTRY_USERNAME" \ - --private-registry-password "$INPUT_PRIVATE_REGISTRY_PASSWORD" \ - ${INPUT_CONFIG_VARIABLES} +if [ "$INPUT_TYPE" == "git" ]; then + BRANCH="$GITHUB_HEAD_REF" + if [ -z "$BRANCH" ]; then + BRANCH="$GITHUB_REF_NAME" + fi + if [ -z "$BRANCH" ]; then + echo "Aborting: branch is not set; this shouldn't happen, please contact support: https://www.aptible.com/docs/support" + exit 1 + fi + + echo "[primetime.aptible.com]:43022 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQClUA3SfI+5YthgM/tZ2k1oCYgK+8KbhbVeMdhgHqyKuY/lh7If13MBpxJzyRWs7YEJc+I0D1y3BRQlUe5+xBp4yYKCsbzKJDIvIx/fWWYQugrtxCskXxCQreNzONoB3ibaHQ21N1xCMk+CgLeu+PpCwb1bOxnu+aoz6o73NdOZLnlvadGlojs59datshEyY+l/ZikZ2TIOZUqdzrF3ValivNV9dQeskNLIYdlKkjoO/E+xg/wV9T8LMFa1VXqWiF9+LWuoiCfGqfk6Xz33DPrADtiMKOJj9uWshwxr5L2HAN+aLz2SAW9aaDwHObLMkThhtwJ3qOg+QGGzVOZQpxkOShYb5ByemhKKL6fHo5c2wVOq0QCmoaG/GfGZm24dRdBgj2GHrr1BAQCIN6LDYVU/NHOAgOzdgsGljbtrZ6RGx9waE/QYCnnG6rUz0o7Y+cQOotiQvu2CxOccpkiwwn+olkCrzrApWgs4yloM7mfvsXjCctJHv7ClwUP/iiYpxkc=" >> ./known_hosts + echo "[primetime.aptible.com]:43022 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEHFh32OAG4rBx9Nisn2RBVbVxkKNrWi/4M6Q44fVwKZEFSUaAJifIk97zd8MhFcsV1WfvOUGIH3s9Png/mWh3A=" >> ./known_hosts + export ACCESS_TOKEN=$(cat "$HOME/.aptible/tokens.json" | jq '.["https://auth.aptible.com"]' -r) + REMOTE_URL="root@$INPUT_GIT_REMOTE:$INPUT_ENVIRONMENT/$INPUT_APP.git" + git remote add aptible ${REMOTE_URL} + REMOTE_BRANCH="deploy-$(date "+%s")" + GIT_SSH_COMMAND="ssh -o SendEnv=ACCESS_TOKEN -o PubkeyAuthentication=no -o UserKnownHostsFile=./known_hosts -p 43022" git push aptible "$BRANCH:$REMOTE_BRANCH" + + aptible deploy --environment "$INPUT_ENVIRONMENT" \ + --app "$INPUT_APP" \ + --git-commitish "$REMOTE_BRANCH" \ + ${INPUT_CONFIG_VARIABLES} +fi + +if [ "$INPUT_TYPE" == "docker" ]; then + if [ -z "$INPUT_DOCKER_IMG" ]; then + echo "Aborting: docker_img is not set" + exit 1 + fi + + aptible deploy --environment "$INPUT_ENVIRONMENT" \ + --app "$INPUT_APP" \ + --docker-image "$INPUT_DOCKER_IMG" \ + --private-registry-username "$INPUT_PRIVATE_REGISTRY_USERNAME" \ + --private-registry-password "$INPUT_PRIVATE_REGISTRY_PASSWORD" \ + ${INPUT_CONFIG_VARIABLES} +fi