Skip to content



Make sure that the following prerequisites are met:

  • Python (3.8, 3.9 or 3.10) is installed
  • Docker is installed
  • The latest release of Poetry is installed

Bootstrap a new project

Create a pyproject.toml file with general information on your extension project:

$ mkdir tshirt_extension
$ cd tshirt_extension
$ poetry init --name tshirt-extension --description "T-Shirt extension" --author "Globex corporation" --python ">=3.8,<3.11" --dependency="connect-eaas-core>=30.0,<31" --no-interaction

Use the poetry init command to create a pyproject.toml file with the following data:

name = "tshirt-extension"
version = "0.1.0"
description = "T-Shirt extension"
authors = ["Globex corporation"]
readme = ""
packages = [{include = "tshirt_extension"}]

python = ">=3.8,<3.11"
connect-eaas-core = ">=30.0,<31"

requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Next, create a root python package for your project, a readme file and a changelog file:

$ mkdir tshirt_extension
$ touch
$ touch

Create a descriptor file

Create a descriptor file with essential information on your extension project. Use the following command to create an empty JSON file inside your extension root package:

$ touch tshirt_extension/extension.json


The name of your descriptor file must always be extension.json. It also must be located inside the root package of your extension project.

Next, open your created extension.json file by using your code editor and provide the following data:

    "name": "tshirt",
    "description": "This extension allows create a purchase order for a t-shirt using an Anvil Client Application.",
    "version": "1.0.0",
    "audience": ["distributor"],
    "readme_url": "",
    "changelog_url": ""


All the attributes of the extension.json descriptor are mandatory.

The provided example assumes that your extension code will be hosted on within the myaccount account and your repository is called tshirt_extension.

The audience attribute represents a list of account roles in Connect. Thus, it is required to specify which roles are supported by your extension. For hub integration extensions, it is required to specify ["distributor"] and/or ["reseller"] roles.

The readme_url and changelog_url will be presented in the Connect UI DevOps module as a reference for teams that will work with your extension.

Dockerfile and docker-compose.yml

Create a dockerfile and a docker-compose.yml and to run your extension locally. First, add a new docker-compose.yml file to your project root folder:

$ touch docker-compose.yml

Populate your docker-compose.yml with necessary data as follows:

version: '3'

    container_name: tshirt_dev
      context: .
    working_dir: /extension
    command: cextrun -d
      - .:/extension
      - .tshirt_dev.env

    container_name: tshirt_bash
      context: .
    working_dir: /extension
    command: /bin/bash
    stdin_open: true
    tty: true
      - .:/extension
      - .tshirt_dev.env

    container_name: tshirt_test
      context: .
    working_dir: /extension
    command: extension-test
      - .:/extension
      - .tshirt_dev.env

Next, create an empty dockerfile by using the following command:

$ touch Dockerfile

Add the following code to your dockerfile:

FROM cloudblueconnect/connect-extension-runner:29.4

COPY pyproject.toml /install_temp/.
COPY poetry.* /install_temp/.
WORKDIR /install_temp
RUN poetry update && poetry install --no-root
COPY package*.json /install_temp/.
RUN if [ -f "/install_temp/package.json" ]; then npm install; fi

Create .tshirt_dev.env

Make sure to add a new env file with your environment variables:

$ touch .tshirt_dev.env

Enter the following variables within your created env file:

API_KEY="<< replace with a Connect API key >>"
ENVIRONMENT_ID="<< replace with your DevOps environment ID >>"