|
| 1 | +# Configure CI/CD |
| 2 | + |
| 3 | +There are many CI/CD pipelines available, but it's probably best to stick with the pipeline system that's tied with your VCS (version control system), like [Github Actions][1] for Github, [Gitlab CI][2] for Gitlab and [Bitbucket Pipelines][3] for Bitbucket. |
| 4 | + |
| 5 | +In this example we'll be covering the Github Actions CI/CD configuration. |
| 6 | + |
| 7 | +## Prepare the secrets |
| 8 | + |
| 9 | +Hypernode Deploy needs a few 'credentials' to be able to function. The necessary credentials are: |
| 10 | + |
| 11 | +1. The private SSH key. (`SSH_PRIVATE_KEY`) |
| 12 | +2. The composer auth.json file, optional. (`DEPLOY_COMPOSER_AUTH`) |
| 13 | + - This is only necessary when your project needs to access private Composer repositories. |
| 14 | +3. The Hypernode API token, optional. (`HYPERNODE_API_TOKEN`) |
| 15 | + - This is only necessary when you make use of Hypernode API driven features like Brancher. |
| 16 | + |
| 17 | +These credentials can usually be stored as 'secret' environment variables in the pipeline system. |
| 18 | + |
| 19 | +### Private SSH key |
| 20 | + |
| 21 | +If you don't have a dedicated SSH key used for deploying the application, open up a terminal and run the following command: |
| 22 | + |
| 23 | +```console |
| 24 | +$ ssh-keygen -f deploy.key -N '' |
| 25 | +Generating public/private rsa key pair. |
| 26 | +Your identification has been saved in deploy.key |
| 27 | +Your public key has been saved in deploy.key.pub |
| 28 | +The key fingerprint is: |
| 29 | +SHA256:qEYqQ7WfL8MEHDnjntKUQwJQl1+RjAnX/gvGHS9a60w timon@thinkus |
| 30 | +The key's randomart image is: |
| 31 | ++---[RSA 3072]----+ |
| 32 | +|=.. +o.=.o | |
| 33 | +| . B..o = | |
| 34 | +| =.=. o | |
| 35 | +| .B. ... . | |
| 36 | +| .+.= ..So o | |
| 37 | +|.. *.o. + = . | |
| 38 | +|o o =o . +E+ | |
| 39 | +| o . +. .oo | |
| 40 | +| o. .o | |
| 41 | ++----[SHA256]-----+ |
| 42 | +``` |
| 43 | + |
| 44 | +Copy the contents of the private key file (`deploy.key` in example above). |
| 45 | + |
| 46 | +Then go to your Github repository on Github.com and go to **Settings -> Secrets -> Actions**. Click the **New repository secret**, fill in `SSH_PRIVATE_KEY` as the name, paste the contents of your key file and press **Save**. |
| 47 | + |
| 48 | +Then copy the contents of the public key file (`deploy.key.pub`) and paste the contents as a new line entry in the `~/.ssh/authorized_keys` file of each relevant server (for this example staging and production). This enables us to authenticate ourselves to the servers from the CI/CD system. |
| 49 | + |
| 50 | +### Composer authentication |
| 51 | + |
| 52 | +***Optional step*** |
| 53 | + |
| 54 | +We assume you have an `auth.json` file in either your project directory or your Composer home directory. Copy the contents of this file. |
| 55 | + |
| 56 | +Then go to your Github repository on Github.com and go to **Settings -> Secrets -> Actions**. Click the **New repository secret**, fill in `DEPLOY_COMPOSER_AUTH` as the name, paste the contents of your `auth.json` file and press **Save**. |
| 57 | + |
| 58 | +### Hypernode API authentication |
| 59 | + |
| 60 | +***Optional step*** |
| 61 | + |
| 62 | +We assume you want to use the Hypernode Brancher feature to spin up temporary nodes based on a specific Hypernode. SSH into that Hypernode and copy the contents of the `/etc/hypernode/hypernode_api_token` file. |
| 63 | + |
| 64 | +Then go to your Github repository on Github.com and go to **Settings -> Secrets -> Actions**. Click the **New repository secret**, fill in `HYPERNODE_API_TOKEN` as the name, paste the contents of your `hypernode_api_token` file and press **Save**. |
| 65 | + |
| 66 | +## Create the workflow file |
| 67 | + |
| 68 | +Create the `.github/workflows` directory structure: |
| 69 | + |
| 70 | +```console |
| 71 | +$ mkdir -p .github/workflows |
| 72 | +``` |
| 73 | + |
| 74 | +In that directory, create a file named `deploy.yaml` and fill in the following contents: |
| 75 | + |
| 76 | +```yaml |
| 77 | +name: Build and deploy application |
| 78 | + |
| 79 | +on: |
| 80 | + push: |
| 81 | + branches: |
| 82 | + - 'master' # Your main/master/production branch |
| 83 | + - 'staging' # Your staging/acceptance branch |
| 84 | +``` |
| 85 | +
|
| 86 | +### Build step |
| 87 | +
|
| 88 | +The first thing we want to run is the `build` step, which does all the dirty work to prepare the application for the web. Add the following configuration to the `deploy.yaml` file. |
| 89 | + |
| 90 | +```yaml |
| 91 | +env: |
| 92 | + COMPOSER_CACHE_DIR: /tmp/composer-cache |
| 93 | +
|
| 94 | +jobs: |
| 95 | + build: |
| 96 | + runs-on: ubuntu-latest |
| 97 | + # Here we use the Hypernode Deploy v3 image with PHP 8.1 and Node.js 18 |
| 98 | + container: quay.io/hypernode/deploy:3.0-php8.1-node18 |
| 99 | + steps: |
| 100 | + - uses: actions/checkout@v2 |
| 101 | + - uses: actions/cache@v2 |
| 102 | + with: |
| 103 | + path: /tmp/composer-cache |
| 104 | + key: ${{ runner.os }}-composer |
| 105 | + - uses: webfactory/ssh-agent@v0.5.4 |
| 106 | + with: |
| 107 | + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} |
| 108 | + - run: hypernode-deploy build -vvv |
| 109 | + env: |
| 110 | + DEPLOY_COMPOSER_AUTH: ${{ secrets.DEPLOY_COMPOSER_AUTH }} |
| 111 | + - name: archive production artifacts |
| 112 | + uses: actions/upload-artifact@v3 |
| 113 | + with: |
| 114 | + name: deployment-build |
| 115 | + path: build/build.tgz |
| 116 | +``` |
| 117 | + |
| 118 | +### Deploy step |
| 119 | + |
| 120 | +For the deployment part, add a job called `deploy` to the `jobs` configuration. |
| 121 | + |
| 122 | +```yaml |
| 123 | +... |
| 124 | +
|
| 125 | +jobs: |
| 126 | + build: |
| 127 | + ... |
| 128 | + deploy: |
| 129 | + needs: build |
| 130 | + runs-on: ubuntu-latest |
| 131 | + # Here we use the Hypernode Deploy v3 image with PHP 8.1 and Node.js 18 |
| 132 | + container: quay.io/hypernode/deploy:3.0-php8.1-node18 |
| 133 | + steps: |
| 134 | + - uses: actions/checkout@v2 |
| 135 | + - name: download build artifact |
| 136 | + uses: actions/download-artifact@v3 |
| 137 | + with: |
| 138 | + name: deployment-build |
| 139 | + path: build/ |
| 140 | + - uses: webfactory/ssh-agent@v0.5.4 |
| 141 | + with: |
| 142 | + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} |
| 143 | + - run: mkdir -p $HOME/.ssh |
| 144 | + - name: deploy to staging # Staging deployment happens here |
| 145 | + if: github.ref == 'refs/heads/staging' |
| 146 | + run: hypernode-deploy deploy staging -vvv |
| 147 | + - name: deploy to production # Production deployment happens here |
| 148 | + if: github.ref == 'refs/heads/master' |
| 149 | + run: hypernode-deploy deploy production -vvv |
| 150 | + - name: cleanup acquired resources |
| 151 | + if: ${{ always() }} |
| 152 | + run: hypernode-deploy cleanup |
| 153 | +``` |
| 154 | + |
| 155 | + |
| 156 | +```{note} |
| 157 | +CI/CD configuration templates can be found here: |
| 158 | +- [Github Actions](../pipelines/github-actions.md) |
| 159 | +- [Gitlab CI](../pipelines/gitlab-ci.md) |
| 160 | +- [Bitbucket Pipelines](../pipelines/bitbucket-pipelines.md) |
| 161 | +``` |
| 162 | + |
| 163 | +[1]: <https://github.com/features/actions> |
| 164 | +[2]: <https://about.gitlab.com/features/continuous-integration/> |
| 165 | +[3]: <https://bitbucket.org/product/features/pipelines> |
0 commit comments