Autonomous Development

Imperative Image Construction

Creating an artefact for compiled languages is well understood, and is an integral part of software delivery for languages such as .NET, Java and Typescript, however, for interpretive languages (Python, Ruby, PHP, Javascript), because the code in source control can be run without a “build”, it is tempting to deploy from source control. This has the following challenges:

  • Fulfilling dependencies in production environment, can have network issues and, even with lock files, can result is different runtime outcomes.
  • Manual steps are required as branches are used to separate environments, e.g. test, staging, production. Which requires deploy-time developer effort and can lead to errors, i.e. untested code being merged into production.

Package & Publish

Resolving dependencies at build time, adding any other runtime components and creating an immutable package for deployment can be achieved using the CDAF technology agnostic package mechanism. The “build” artefact completes the development teams Continuous Integration (CI) stage.

The Continuous Delivery (CD) would be limited to automated testing of the package, and then publication. Publication can be to a Container Registry, Package Registry (Nexus, Artifactory, Azure DevOps, GitLab, GitHub, etc.) or a proprietary asset registry such as Octopus Deploy or Mulesoft AnyPoint Exchange. The following example uses a Container Registry.

The following overview has two examples, one using the CDAF release package with automated testing, and one performing direct image build and push.

  • PiP resolves Python dependencies, and gathers these, along with helper scripts, to produce a release package. The release package is then used to construct a runtime image, which in turn is smoke tested using docker-compose. The tested image is then pushed to the registry.

  • NPM resolves NodeJS dependencies, builds an image and pushes it to the registry.

graph LR subgraph python["Python"] python-git[(Git)] python-build-artefact[(Build)] python-release.ps1 subgraph docker-compose image-container test-container end push end subgraph node["NodeJS"] node-git[(Git)] node-build node-push["push"] end registry[(Docker Registry)] python-git -- "CI (PiP)" --> python-build-artefact -- "CD" --> python-release.ps1 --> image-container --> push --> registry test-container -. "smoke test" .-> image-container node-git -- "CI (NPM)" --> node-build --> node-push --> registry classDef dashed stroke-dasharray: 5, 5 class python,node dashed classDef dotted stroke-dasharray: 2, 2 class docker-compose dotted classDef blue fill:#007FFF class registry blue

Note: the Python release.ps1 is an intermediary artefact, and not used to deploy to the runtime environments.