# Automated `dev` release pipeline The following diagram shows the process by which the `dev release` workflow can be triggered. There are two mechanics which may start the work flow: a push to the `develop` branch of the repository, or the presence of changes at a scheduled checkup time outside of work hours (e.g. 3 a.m.) ![](https://i.imgur.com/PjGPmoQ.png) ## `dev` release process - Checks for dependencies that have a higher version priority on the `dev` subchannel. This enables a `dev` release of `tudatpy` to use a `dev` release of `tudat`, if its version is higher than what's available on `main`. - [source for conda-forge versioning](https://conda-forge.org/docs/maintainer/knowledge_base.html#installing-a-pre-release-build) -> **W.I.P** ## Setup Requirements There are a few requirements that need to be setup in the `tudat-team` owned repository for this workflow to work. These requirements are imposed on the project source and the feedstock of the respective project. ### Feedstock --- #### 1. `feedstock/recipe/meta.yaml` --- ````yaml {% set name = "tudat" %} {% set version = "2.9.1.dev0" %} # 1️ ✔️ {% set build = "0" %} # 2️ ✔️ {% set git_rev = "v2.9.1.dev0" %} # 3️ ✔️ package: name: {{ name }} version: {{ version }} # 1️ ✔️ source: git_url: https://github.com/tudat-team/tudat.git git_rev: {{ git_rev }} # 3️ ✔️ build: number: {{ build }} # 2️ ✔️ ```` --- #### 2. `feedstock/recipe/conda_build_config.yaml` --- Exact format must be followed, only for `channel_targets`. The workflow will regex the `- tudat-team dev` and ensure that the subchannel target is correct (e.g. master/main branch -> main subchannel / develop -> dev subchannel). ````yaml channel_targets: - tudat-team dev ```` --- #### 3. `feedstock/conda-forge.yml` --- Again, exact format must be used, the contents of `[...]` will be replaced by the appropriate subchannel. This is to improve robustness from merges between branches in the future. ````yaml channels: targets: - [tudat-team, dev] ```` ### Project --- #### 1. `project/.bumpversion.cfg` --- This file coordinates the version bumping conventions of the project. ````config [bumpversion] current_version = 2.9.1.dev0 commit = True tag = True parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<dev>\d+))? serialize = {major}.{minor}.{patch}.{release}{dev} {major}.{minor}.{patch} [bumpversion:part:release] optional_value = gamma values = dev gamma [bumpversion:part:dev] [bumpversion:file:version] ```` [This library](https://pypi.org/project/bumpversion/), with this configuration, allows for the following commands, with provided examples which explain some of the subtle details to the transitions. - `bumpversion patch` - `1.1.1` -> `1.1.2.dev0` - `1.1.2.dev0` -> `1.1.3.dev0` - `1.1.2.dev1` -> `1.1.3.dev0` - `bumpversion dev` - `1.1.2.dev0` -> `1.1.2.dev1` - `1.1.2` -> ❌ This will break. Patch must be bumped to start `dev` suffix. - `bumpversion release` - `1.1.2.dev0` -> `1.1.2` - `1.2.0.dev0` -> `1.2.0` --- #### 2. `project/version` --- This basic text file (note no extension) is used to keep track of the version of the source code during builds. For example, `CMakeLists.txt` will use this for the CMake project versioning. Also, the [`.github` version tracker](https://github.com/tudat-team#stable-builds-) of all stable and unstable releases will use these files to report the versioning. --- #### 3. `project/.github/workflows/inform.yml` --- This file is the GitHub workflow which is triggered when the project receives a push. This workflow will send a payload of data to the `tudat-team/.github/workflows/webservices.yml` where the core automation takes place. ````yaml name: Inform .github repository ℹ️ on: push: branches: - 'main' - 'master' - 'develop' - 'feature/**' jobs: dispacher: runs-on: ubuntu-latest name: webservices steps: - name: repository-dispatch uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.GH_TOKEN }} repository: tudat-team/.github event-type: push to ${{ github.repository }} client-payload: >- { "event": "${{ github.event_name }}", "actor": "${{ github.actor }}", "repository": "${{ github.repository }}", "ref": "${{ github.ref }}", "ref_name": "${{ github.ref_name }}", "ref_type": "${{ github.ref_type }}", "sha": "${{ github.sha }}" } ```` ## Where's the automation taking place? Under the `Actions` tab of `tudat-team/.github`, you will find the GitHub actions workflows. There you will see a `webservices.yml` workflow which receives a signal from the `project`'s `project/.github/workflows/inform.yml`. ![](https://i.imgur.com/f8OK8sX.png) Here you can see the history of all triggers to the `webservices.yml` workflow. ![](https://i.imgur.com/h06RVYJ.png) Here are the contents of the `webservices.yml` file: ````yaml on: repository_dispatch jobs: webservices: runs-on: ubuntu-latest name: webservices steps: - name: webservices env: GH_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_WORKSPACE: ${{ github.workspace }} GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_EVENT_PATH: ${{ github.event_path }} GITHUB_EVENT_NAME: ${{ github.event_name }} id: webservices uses: tudat-team/webservices-dispatch-action@main with: github_token: ${{ secrets.GH_TOKEN }} ```` A `respository_dispatch` is a way of accepting a message about an event, with optional event data. The workflow can then react according to the event type and the event data provided. In our workflow, we have each of our projects inform this centralized workflow about any pushes that have occured to one of our project repositories (via their respective `inform.yml` workflow). The only thing work taking away here is that we set some environment variables from the [github context](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context) which will be used to provide the central workflow with required information on the event. The next key is: ```` ... uses: tudat-team/webservices-dispatch-action@main ... ```` which is a way of retrieving a reusable workflow, which can be published as a standalone repository. This leads to the [`main.py`](https://github.com/tudat-team/webservices-dispatch-action/blob/main/main.py) file within the `tudat-team/webservices-dispatch-action` repository, where the logic (currently messy) for the automated workflow is coded. ## Further Work - Sequentially build dependencies (e.g. tudat, *then* tudatpy when tudat succeeds) -> **W.I.P**