Automate Appwrite Functions Deployment with GitHub Actions CI
Published: 2021-02-19 16:34:20

With [Appwrite v0.7](https://medium.com/appwrite-io/introducing-appwrite-baas-v0-7-1a73be195a85) we introduced [Cloud Functions](https://appwrite.io/docs/functions) to our Open Source Backend-as-a-Service, which allow custom backend code to customize your Appwrite server. You can deploy your code using both the Appwrite dashboard or the new Appwrite CLI and execute it via the API, specific system events, a predefined schedule, or from your dashboard.

Since developers are lazy - in a good way - we are going to automate the deployment of Appwrite Functions using GitHub Actions.

To make Appwrite as simple as possible to integrate into your CI, we have provided a [GitHub Action in the Marketplace](https://github.com/marketplace/actions/setup-appwrite-cli) which integrates [Appwrite CLI](https://appwrite.io/docs/command-line). This allows you to access and use all the functionality of your Appwrite server.

![Appwrite GitHub Action](https://dev-to-uploads.s3.amazonaws.com/i/quqjo5zonepea83mpm38.png)

## Step 1 - Create a GitHub Action

For this example, I am using a .NET project, but this will work with any language for which Appwrite Functions offers an environment. If you need help with [Node.js](https://docs.github.com/en/actions/guides/building-and-testing-nodejs) or [Python](https://docs.github.com/en/actions/guides/building-and-testing-python), please use the official documentation, or if you are already familiar with GitHub Actions, go straight to Step 2. 

To get started quickly, create `deploy.yml` in the `.github/workflows` directory of your repository:

```yaml
# deploy.yml

name: Deploy .NET function

on:
  push:
    branches: [ $default-branch ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core SDK 5.0
      uses: actions/setup-dotnet@v1.7.2
      with:
        dotnet-version: '5.0'
    - name: Install dependencies
      run: dotnet restore
    - name: Build
      run: dotnet build --configuration Release --no-restore
    - name: Test
      run: dotnet test --no-restore --verbosity normal
```

This workflow file sets up Ubuntu with .NET 5.0, installs all dependencies of the project, builds it and runs all defined tests. 

Firstly, we give our workflow a name to identify it. In my example I am calling it `Deploy .NET function`.

```yaml
name: Deploy .NET function
```

This section defines that the action will be run on every push to the `$default-branch`. In our case, this will be the **main** branch.

```yaml
on:
  push:
    branches: [ $default-branch ]
```

To use a preinstalled version of the .NET Core SDK on a GitHub-hosted runner, we are using the `setup-dotnet` action. This action finds a specific version of .NET from the tools cache on each runner. These changes will persist for the remainder of the job.

The `setup-dotnet` action is the recommended way of using .NET with GitHub Actions, because it ensures consistent behavior across different runners and different versions of .NET.

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core SDK 5.0
      uses: actions/setup-dotnet@v1.7.2
      with:
        dotnet-version: '5.0'
```

The remaining steps should be self-explanatory and we will now deploy our function to our Appwrite server.

## Step 2 - Setup Appwrite CLI

[This action](https://github.com/marketplace/actions/setup-appwrite-cli) will setup Appwrite CLI for all following steps in this job. We are going to add it after `Setup .NET Core SDK 5.0` before our project is built and tested.

```yaml
- uses: appwrite/setup-for-actions@v1
  with:
    endpoint: 'https://[HOSTNAME_OR_IP]/v1'
    project: '${{ secrets.APPWRITE_PROJECT }}'
    key: '${{ secrets.APPWRITE_API_KEY }}'
```

`[HOSTNAME_OR_IP]` needs to be replaced with an address that will point to your Appwrite server. For `project` and `key` we are going to use [GitHub Secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) to prevent leaking any sensitive information like an API key. If you don't know how to add secrets, [click here](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) to read the official documentation.

Create the following secrets in your GitHub repository:

- `APPWRITE_PROJECT`
  - Value needs to be your project ID.
- `APPWRITE_API_KEY`
  - Value needs to be an API Key. Since we want to deploy a function, this key needs to have permission to the `functions.write` scope.

Great! Now you're all set to use the Appwrite CLI. You can access the CLI using the `appwrite` command. After the `test`  we will add another step which uses the CLI to deploy our function:

```yaml
- name: Deploy
  run: |
    appwrite functions createTag \
      --functionId='[FUNCTION_ID]' \
      --command="dotnet appwrite-dotnet-function-example.dll" \
      --code="bin/Release/net5.0/" 
```

`[FUNCTION_ID]` needs to be replaced with the ID of your function which you can find in your Appwrite Dashboard. 

The `--command` argument is the command that will be run each time your function is executed. For **Node.js** it would be something like `node index.js`. 

The `--code` argument points to where your function is stored. If your function is stored in the root of your repository, you can use `--code="."` to package and deploy your whole repository.

You can find the [complete workflow file here](https://github.com/TorstenDittmann/appwrite-dotnet-function-example/blob/main/.github/workflows/deploy.yml).

## Steps 3 - Push and deploy a function

After this workflow file is pushed to your GitHub repository, GitHub will automatically run it and you can find the logs in the **Actions** section on your GitHub repository. 

![GitHub Actions](https://dev-to-uploads.s3.amazonaws.com/i/r7z4aev4h2h63716ris4.png)

This action compiled my .NET project and deployed it to my Appwrite Server. In the Appwrite dashboard under my function, I can find it in the tags.

![Appwrite Functions](https://dev-to-uploads.s3.amazonaws.com/i/06v8jb0naafsfodc5poy.png)

## Conclusion

GitHub recently made Actions free for private repository, along with 2000 build minutes per month. This allows you to automate [Appwrite Functions](https://appwrite.io/docs/functions) deployment using [our GitHub action](https://github.com/marketplace/actions/setup-appwrite-cli).

If you need help or encounter any difficulties setting up Appwrite in your CI, please [join our Discord](https://appwrite.io/discord).

### References

- [Appwrite GitHub Action](https://github.com/marketplace/actions/setup-appwrite-cli)
- [Appwrite Functions](https://appwrite.io/docs/functions)
- [Appwrite v0.7 Announcement](https://medium.com/appwrite-io/introducing-appwrite-baas-v0-7-1a73be195a85)
- [Appwrite Discord](https://appwrite.io/discord)
- [Appwrite Documentation](https://appwrite.io/docs)
- [Demo Repository](https://github.com/TorstenDittmann/appwrite-dotnet-function-example/)