This directory contains documentation for people working on/developing Sematic
itself. Documents intended for users of Sematic are in the docs directory,
and are published to https://docs.sematic.dev/
The developer tools need to be installed by running this command once (and subsequently
whenever requirements/ci-requirements.txt) will be updated:
$ make install-dev-depsGuideline for testing changes that might impact pipeline runs:
- the CI tests must pass
- test locally
- test remotely in non-detached mode
- test remotely in detached mode
In order to ensure the PR review goes swiftly, please:
- Add a comprehensive description to your PR
- Ensure your code is properly formatted and type checked
- Make sure you have the dev tools installed by running
make install-dev-deps(you only ever need to do this once) - Use
make pre-committo run the linter and code formatter - Use
make update-schemato make sure any DB changes you made are accounted for
- Make sure you have the dev tools installed by running
- Make sure the CircleCI build passes for your branch (linked in the checks section at the bottom of the GitHub PR page)
- Add
sematic-ai/staffas a reviewer, but also try to assign a specific reviewer, such asneutralino1
The user settings are saved to the
~/.sematic/settings.yaml files, under the "default" entry. Example:
$ cat ~/.sematic/settings.yaml
default:
SEMATIC_API_ADDRESS: http://127.0.01:5001
SEMATIC_API_KEY: XXXThese are accessible through the CLI commands for more user-friendliness:
$ sematic settings show
Active user settings:
SEMATIC_API_ADDRESS: http://127.0.0.1:5001
SEMATIC_API_KEY: <my_local_api_key>When developing, we often need to switch the Server where we submit pipelines,
sometimes bundled together with other settings as well. In order to avoid
constantly editing this file manually, we can define one file per environment
or profile, under the names ~/.sematic/settings.yaml.<profile>, and switch
between them using bazel run //tools:switch-settings -- <profile>.
This actually copies these profile files over the main settings file. Example:
$ bazel run //tools:switch-settings -- prod1
[...]
Copying previous settings to /Users/tudorscurtu/.sematic/settings.yaml_bck
Copying /Users/tudorscurtu/.sematic/settings.yaml.prod1 to /Users/tudorscurtu/.sematic/settings.yaml
Successfully switched to prod1!
$ sematic settings show
Active user settings:
SEMATIC_API_ADDRESS: https://<my_prod1_host:port>
SEMATIC_API_KEY: <my_prod1_api_key>If you want to build the wheel from source, do:
$ make ui
$ make wheelWhen modifying existing tables in the database, there are some important differences in the types of operations that are supported by SQLite, and so care must be taken to ensure that the migration works for both types of databases.
[SQLite ALTER TABLE docs] (https://www.sqlite.org/lang_altertable.html) explain this well.
If your PR does need to perform database-specific migrations, you can use one of the
existing migrations in sematic/db/migrations that do this as a reference. All PRs that
are affected by the table modification incompatibilities must resolve the issue in this
manner.
Note: Actually pushing the artifacts and accessing some of the repositories listed in this section can only be done if you have access to the PyPI repo, which is limited to employees of Sematic.
We cut releases from the main branch, following the steps below. They must be
performed in order, without skipping any. If any errors occur, you must fix
them and then go back and redo all the steps that have been affected by the
changes.
-
Announce internally that a
mainmerge freeze has started. -
Bump the version in:
wheel_constants.bzl-wheel_version_stringhelm/sematic-server/Chart.yaml-appVersionsematic/versions.py-CURRENT_VERSION; bumpMIN_CLIENT_SERVER_SUPPORTSif there are any TODOs mentioning this should be done./README.md- PyPI badge
-
Increment the patch version of the
versionfield inhelm/sematic-server/Chart.yaml. Note that this will be DIFFERENT from the Sematic version you changed in prior steps (chart version will be1.X.Y, Sematic version is0.M.N). -
Update
changelog.mdwith the new version number and any missing change entries. -
Build the UI:
$ make ui
-
Build the wheel:
$ make wheel
-
Test the Server wheel locally for all supported versions of Python.
-
Copy the wheel from
bazel-bin/sematic/sematic-*.whlinto a scratch directory. -
For each supported version of Python, use a virtual env to test:
$ # LOCALLY: $ pip3 install <wheel path> $ sematic stop $ sematic version # check that the correct sematic and python versions are used $ sematic start $ sematic run examples/mnist/pytorch $ sematic stop
-
-
Test the internal Helm charts deployment.
-
Test an upgrade deployment in the
stageenvironment, where the previous version is already deployed, useserve-devto upgrade the deployment with a Docker image built on-the-fly from the current release commit. You must setBUILD_UI=1in theme.shscript in order to ensure the UI is built, so you don't package an older version of the UI with the deployment:$ vim ~/infrastructure/bin/me.sh # add: BUILD_UI=1 at the end $ # STAGE: $ serve-dev stage $ helm list -n stage # check that the expected APP VERSION was deployed
-
Smoke test new features that were included or significantly updated in the release.
-
Run the Testing Pipeline with the test cases listed below on this deployment, and check that it completes successfully, while perusing its outputs and logs to check that they render correctly.
$ # STAGE: $ bazel run sematic/examples/testing_pipeline:__main__ -- \ --cloud \ --detach \ --max-parallelism 10 \ --inline \ --nested \ --no-input \ --sleep 10 \ --spam-logs 1000 \ --fan-out 10 \ --raise-retry 0.7 \ --external-resource \ --expand-shared-memory \ --mount-host-path /tmp /test \ --mount-host-path /tmp /test2 \ --cache-namespace test \ --images \ --virtual-funcs \ --fork-subprocess return 0 \ --fork-subprocess exit 0 \ --fork-subprocess exit 1 \ --fork-subprocess signal 2 \ --fork-subprocess signal 15
-
Test client backwards compatibility. Install the version of Sematic that matches
MIN_CLIENT_SERVER_SUPPORTSfromsematic/versions.pyin a virtual env and validate that this older client can run a packaged example pipeline end-to-end successfully on the new Server.$ sematic version # check that the correct min version is installed $ STAGE: $ sematic run examples/mnist/pytorch -
Test a clean installation in the same
stageenvironment.$ # STAGE: $ helm uninstall sematic-server -n stage $ helm list -n stage # check that the chart was uninstalled $ serve-dev stage $ helm list -n stage # check that the expected APP VERSION was deployed
-
Wait a few minutes for AWS to bootstrap the services and network configuration. Smoke test that a simple pipeline succeeds, this time in local mode, to cover that aspect as well.
$ # STAGE: $ bazel run sematic/examples/testing_pipeline:__main__
-
-
Test publishing the wheel. Check if the generated webpage on
test.pypi.orgis rendered correctly.$ make test-release
-
Make the release PR, containing all version changes and required fixes for issues discovered during validation. Even the previous step compiled documentation changes that must be included. After implementing comments and getting approval on the release PR, merge it and pull from the updated
mainbranch. It is mandatory to include this updated version ofmainin the subsequent steps. -
Publish the wheel. Check if the generated webpage on
pypi.orgis rendered correctly.$ make release
If you have 2FA enabled for your account, you need to use an API token as password and
__token__ as username when prompted by the CLI for credential. To set up a pypi.org
API token, go to "Account Settings" -> "API tokens".
Instead of manually typing the username and password, one can also edit ~/.pypirc, adding
below:
[pypi] username = __token__ password = <the token>
-
Add the git tag.
$ export RELEASE_VERSION=v$(python3.9 ./sematic/versions.py) $ git tag $RELEASE_VERSION $ git push origin $RELEASE_VERSION
-
Announce internally that the
mainmerge freeze is over. -
Build and push the Server Docker image. Use the Dockerfile at
docker/Dockerfile.server.$ TAG=v$(python3.9 ./sematic/versions.py) make release-server -
Next you can generate the Helm package and publish it to the Helm repository.
-
[First time setup]Clone the repo withgit clone git@github.com:sematic-ai/helm-charts.git, and check out thegh-pagesbranch in it. The commands below assume thehelm-chartsrepo has been cloned into the~/code/helm-chartsdirectory, but they should be run from the root of thegithub.com/sematic-ai/sematicrepo directory. -
Make sure your
helm-chartsproject'sgh-pagesbranch is up-to-date.$ cd ~/code/helm-charts $ git checkout gh-pages $ git pull $ cd ~/code/sematic
-
Generate the updated Helm package from the Sematic repo.
$ export HELM_REPO=~/code/helm-charts $ helm package helm/sematic-server $ helm repo index . \ --url https://sematic-ai.github.io/helm-charts/sematic-server \ --merge $HELM_REPO/index.yaml $ mv index.yaml $HELM_REPO/index.yaml $ mv *.tgz $HELM_REPO/sematic-server/
-
(OPTIONAL) Only do this step if you know that the Sematic Grafana dashboards have been updated and need to be released. Generate the updated Helm package from the Sematic repo.
$ export HELM_REPO=~/code/helm-charts $ helm package helm/sematic-grafana-dashboards $ helm repo index . \ --url https://sematic-ai.github.io/helm-charts/sematic-grafana-dashboards \ --merge $HELM_REPO/index.yaml $ mv index.yaml $HELM_REPO/index.yaml $ mv *.tgz $HELM_REPO/sematic-grafana-dashboards/
-
You should now have a new
sematic-server/sematic-server-X.X.X.tgzfile in thehelm-chartsrepo, and a modifiedindex.yamlfile. If you optionally created a package for the Grafana dashboards, you should also have asematic-grafana-dashboards/sematic-grafana-dashboards-X.X.X.tgzfile in thehelm-chartsrepo. Commit and push all of these to a new release branch, and create a PR for the change based ongh-pages. Wait for approval, and merge it.
-
-
Deploy this new official release to the
stageenvironment, in order to leave it in a consistent and expected state, and to test the actual commands users will be using to deploy the release.$ # Run this step if it has never been done before $ helm repo add sematic-ai https://sematic-ai.github.io/helm-charts $ # STAGE: $ helm repo update $ helm upgrade sematic-server sematic-ai/sematic-server -n stage -f /path/to/stage_values.yml $ helm list -n stage # check that the expected APP VERSION was deployed
-
Finally, draft the release on GitHub, from the tag you previously committed:
- Pick the
"previous tag"from the dropdown to refer to the previous release. - Add a
"## What's Changed"section, and copy the newly added section of thechangelog.md. - Add a
"Full Changelog"link, and validate it. - Add a
"# Helm Chart Versionsection, and list theappVersionfield here fromhelm/sematic-server/Chart.yaml. - Add a
"## Compatibility"section which states that only clients versions down toMIN_CLIENT_SERVER_SUPPORTSfromsematic/versions.pyare supported. - If
docs/upgrades.mdcontains an entry for upgrading to the released version, add an"## Upgrade Instructions"section, and list and link this documentation entry. - Add a
"## New Contributors"section, if this applies. List all external contributors who have made commits since the last release, and thank them. - Attach the wheel in the
"Assets"section.
- Pick the
If an issue is discovered on the latest release which impacts users to an extent that
warrants a hotpatch, then instead of performing the release from the main branch, we:
- create a separate hotpatch release branch starting from the previous release tag and switch to that branch
- fix the issue and merge it into the release branch via either the normal PR review procedure, or by merging directly in time sensitive situations
- follow all the other steps from the Releasing section
- switch to the
mainbranch, cherry-pick all the changes contained in the hotpatch branch, and merge a PR with these commits
Sometimes we want to cut releases that contain only a subset of changes that
have been included in the main branch since the previous release. In these
cases, instead of performing the release from the main branch, we:
- create a separate release branch starting from the previous release tag and switch to that branch
- cherry-pick the commits we want to include
- follow all the other steps from the Releasing section
- switch to the
mainbranch, make a commit that contains the previous version increase and reconciles the changelog, and merge a PR with this commit
The image used for most of our CircleCi steps is built using docker/Dockerfile.ci.
After updating it, open a PR with the change, push the image to Dockerhub using the PR
number as a tag (in order to be able to maintain a history, and revert, if necessary),
and update the SEMATIC_CI_IMAGE env var in the CircleCi project settings.