Estafette extensions

extensions/git-clone

git-clone:
  image: extensions/git-clone:stable
  shallow: '< boolean | true >'

The git-clone stage is automatically injected if not present in your manifest for the build stages; in the release stages it's not injected. In case you don't need anything from your repository to release this speeds things up.

The shallow clone - enabled by default - checks out the latest 50 commits for the particular branch, then selects the correct revision. When rebuilding an older version or releasing an older version this might not be enough, in that case explicitly set shallow: false.

cloning another repository from the same owner

You can use the git-clone extension to clone another repository as well, as long as it's from the same owner. In order to make use of it you need to specify the repository name (without owner), and optionally the branch you want to clone (defaults to master) and the subdir to clone it into (defaults to the repository name).

clone-another-repo:
  image: extensions/git-clone:stable
  shallow: '< boolean | true >'
  repo: '< string >'
  branch: '< string | master >'
  subdir: '< string | repo >'

Notes:

  • Make sure to avoid the stage name git-clone if you're cloning another repository in one of your stages, because the regular repository will not be cloned automatically in that case.

extensions/docker

The docker extension supports the following actions: build, push, tag. For pushing and tagging containers it uses the credentials and trusted images configuration in the Estafette server to get access to Docker registry credentials automatically.

build
bake:
  image: extensions/docker:stable
  action: build
  no-cache: '< bool | false >'
  expand-variables: '< bool | true >'
  container: '< string | ESTAFETTE_GIT_NAME >'
  repositories:
  - estafette
  path: '< string | . >'
  dockerfile: '< string | Dockerfile >'
  copy:
  - < string | copies Dockerfile by default >
  - /etc/ssl/certs/ca-certificates.crt

The no-cache options ensures that no previous container built for your branch gets used, but it absolutely uses the latest version of the image in your FROM statement.

The expand-variables option allows you to turn off variable expansion, in case you use $PATH or another frequently set variable in your Dockerfile.

A minimal version when using all defaults looks like:

bake:
  image: extensions/docker:stable
  action: build
  repositories:
  - estafette

If you'd like to avoid having a separate Dockerfile you can inline it as well.

  bake:
    image: extensions/docker:stable
    action: build
    inline: |
      FROM scratch
      COPY ca-certificates.crt /etc/ssl/certs/
      COPY ${ESTAFETTE_GIT_NAME} /
      ENTRYPOINT ["/${ESTAFETTE_GIT_NAME}"]
    repositories:
    - estafette
    path: ./publish
    copy:
    - /etc/ssl/certs/ca-certificates.crt
push
push:
  image: extensions/docker:stable
  action: push
  container: '< string | ESTAFETTE_GIT_NAME >'
  repositories:
  - estafette
  tags:
  - < string | tags with ESTAFETTE_BUILD_VERSION by default and is always pushed >
  - dev

A minimal version when using all defaults looks like:

push:
  image: extensions/docker:stable
  action: push
  repositories:
  - estafette
tag

To later on tag a specific version with another tag - for example to promote a dev version to stable you can use the docker extension to tag that version with other tags:

tag:
  image: extensions/docker:dev
  action: tag
  container: '< string | ESTAFETTE_GIT_NAME >'
  repositories:
  - estafette
  tags:
  - stable
  - latest
tag:
  image: extensions/docker:stable
  action: tag
  repositories:
  - estafette
  tags:
  - latest

extensions/gke

The gke extension is used to deploy an application to Kubernetes Engine. It generates a very opinionated deployment with a sidecar. It asumes horizontal pod autoscaling, it injects secrets and configs in a standard way, and uses a lot of other sensible defaults to be able to use it with a minimum number of parameters specified.

By default it includes an OpenResty sidecar handling incoming traffic and forwarding requests. (This is the custom openresty image injected by default.) The sidecar configuration can be adjusted, and additional sidecars can be included by customizing the sidecars field. (The only other type currently supported is the cloudsqlproxy, which adds the proxy implementing secure communication with Google Cloud SQL databases.)
If you don't want to use the default sidecar, you should add the injecthttpproxysidecar: false field to the deployment, then it will not be injected during the development.

deploy:
  image: extensions/gke:stable
  credentials: '< string | gke-ESTAFETTE_RELEASE_NAME >'
  app: '< string | ESTAFETTE_GIT_NAME >'
  namespace: '< string | default namespace from credentials config >'
  visibility: '< string | private >'
  container:
    repository: '< string >'
    name: '< string | app >'
    tag: '< string | ESTAFETTE_BUILD_VERSION >'
    port: '< integer | 5000 >'
    env:
      MY_CUSTOM_ENV: value1
      MY_OTHER_CUSTOM_ENV: value2
    cpu:
      request: '< string | 100m >'
      limit: '< string | 125m >'
    memory:
      request: '< string | 128Mi >'
      limit: '< string | 128Mi >'
    liveness:
      path: '< string | /liveness >'
      delay: '< integer | 30 >'
      timeout: '< integer | 1 >'
    readiness:
      path: '< string | /readiness >'
      delay: '< integer | 0 >'
      timeout: '< integer | 1 >'
    metrics:
      scrape: '< boolean | true >'
      path: '< string | /metrics >'
      port: '< integer | .container.port >'
  sidecars:
  - type: '< string | openresty | cloudsqlproxy >'
    image: '< string | estafette/openresty-sidecar:1.13.6.2-alpine | gcr.io/cloudsql-docker/gce-proxy:1.13 >'
    env:
      CORS_ALLOWED_ORIGINS: "*"
      CORS_MAX_AGE: "86400"
    cpu:
      request: '< string | 10m >'
      limit: '< string | 50m >'
    memory:
      request: '< string | 10Mi >'
      limit: '< string | 50Mi >'
    # Only relevant for cloudsqlproxy
    dbinstanceconnectionname: my-gcloud-project:europe-west1:my-database
    sqlproxyport: 5043
  # Additional sidecars can be listed here.
  - type: '< string | openresty | cloudsqlproxy >'
    image: '< string | estafette/openresty-sidecar:1.13.6.2-alpine | gcr.io/cloudsql-docker/gce-proxy:1.13 >'
    ...
  replicas: '< integer | 0 >'
  autoscale:
    enabled: '< bool | true >'
    min: '< integer | 3 >'
    max: '< integer | 100 >'
    cpu: '< integer | 80 >'
    safety:
      enabled: '< bool | false >'
      promquery: '< string | sum(rate(nginx_http_requests_total{app='app'}[5m])) by (app) >'
      ratio: '< float | 1.0 >'
      delta: '< float | 0.0 >'
      scaledownratio: '< float | 1.0 >'
  secrets:
    keys:
      secret-file-1.json: c29tZSBzZWNyZXQgdmFsdWU=
      secret-file-2.yaml: YW5vdGhlciBzZWNyZXQgdmFsdWU=
    mountpath: /secrets
  configs:
    # these are local files with golang template style placeholders, replaced with the values specified in the data section;
    # set clone: true on the release target to ensure you have access to these files stored in your repository
    files:
    - config/config.json
    - config/anotherconfig.yaml
    # these are the values for the placeholders specified as {{.property1}} to be replaced in the config files
    data:
      property1: value 1
      property2: value 2
    # if you want to avoid cloning your repository and just need to pass a very short config you can inline full files here
    inline:
      inline-config.properties: |
        enemies=aliens
        lives=3
    mountpath: /configs
  manifests:
    files:
    - override/service.yaml
    data:
      property3: value 3
  hosts:
  - gke.estafette.io
  - gke-deploy.estafette.io
  basepath: '< string | / >'
  enablePayloadLogging: '< boolean | false >'
  chaosproof: '< boolean | false >'
  rollingupdate:
    maxsurge: '< string | 25% >'
    maxunavailable: '< string | 25% >'
    timeout: '< string | 5m >'
  trustedips:
  - 103.21.244.0/22
  - 103.22.200.0/22
  - 103.31.4.0/22
  dryrun: '< boolean | false >'

A very minimal version when using all the defaults looks like:

production:
  stages:
    deploy:
      image: extensions/gke:stable
      visibility: private
      container:
        repository: estafette
      hosts:
      - ci.estafette.io

Default visibility is set to private, which creates an internal ingress and it makes the service accessible from within same network. Other supported visibilities are public-whitelist, iap, apigee and esp.

For visibility esp, useGoogleCloudCredentials and disableServiceAccountKeyRotation should be set to true, espOpenapiYamlPath must be set and exactly one host must be provided. e.g.:

production:
  stages:
    deploy:
      image: extensions/gke:stable
      visibility: esp
      useGoogleCloudCredentials: true
      disableServiceAccountKeyRotation: true
      espOpenapiYamlPath: openapi.dev.yaml

For visibility iap, base64 encoded values of iapOauthClientID and iapOauthClientSecret must be provided. e.g.:

production:
  stages:
    deploy:
      image: extensions/gke:stable
      visibility: iap
      iapOauthClientID: aSBhbSBzb21lIGNsaWVudAo= # base64 encoded client ID
      iapOauthClientSecret: estafette.secret(...) # base64 encoded client secret

For visibility apigee, authsecret under request must refer to a Secret containing certificate for client authentication. e.g.:

production:
  stages:
    deploy:
      image: extensions/gke:stable
      visibility: apigee
      request:
        authsecret: nginx-open/org-ca-cert

extensions/github-status

set-build-status:
  image: extensions/github-status:stable
  status: '< string | ESTAFETTE_BUILD_STATUS >'

The github-status extension takes the build status from the ESTAFETTE_BUILD_STATUS environment variable, but this can be overridden with the status tag. Depending on the source of the git push - github or bitbucket - this extension is automatically injected at the beginning of the build stages and at the end in order to set the build status in the respective source code hosting system:

set-pending-build-status:
  image: extensions/github-status:stable
  status: pending

...

set-build-status:
  image: extensions/github-status:stable
  when:
    status == 'succeeded' || 
    status == 'failed'

extensions/bitbucket-status

set-build-status:
  image: extensions/bitbucket-status:stable
  status: '< string | ESTAFETTE_BUILD_STATUS >'

The bitbucket-status extension takes the build status from the ESTAFETTE_BUILD_STATUS environment variable, but this can be overridden with the status tag. Depending on the source of the git push - github or bitbucket - this extension is automatically injected at the beginning of the build stages and at the end in order to set the build status in the respective source code hosting system:

set-pending-build-status:
  image: extensions/bitbucket-status:stable
  status: pending

...

set-build-status:
  image: extensions/bitbucket-status:stable
  when:
    status == 'succeeded' || 
    status == 'failed'

extensions/slack-build-status

slack-notify:
  image: extensions/slack-build-status:stable
  workspace: estafette
  channels:
  - '#mychannel'
  when:
    status == 'succeeded' || 
    status == 'failed'

In order to send build notifications to one or more Slack channels the slack-build-status extension automatically sends a messages depending on the build status into the channels passed to this extension for the workspace you've set.

Notes:

  • This extension uses the credentials and trusted images configuration in the Estafette server to gain access to the slack webhooks configured there.
  • To provide a custom title, you can use title optional input. This will override the title usually composed by the extension.
slack-notify:
  image: extensions/slack-build-status:stable
  workspace: estafette
  channels:
  - '#mychannel'
  title: Releasing!
  when:
    status == 'succeeded' || 
    status == 'failed'
  • If you only want to send a message on failure use
  when:
    status == 'failed'

extensions/npm-audit

stages:
  audit:
    image: extensions/npm-audit:stable
    action: audit
    level: low
    dev-level: none
    workspace: estafette
    channels:
    - '#builds-${ESTAFETTE_LABEL_TEAM}'

audit

For now the only supported action is audit

level

This is the level you set to check for the vulnerabilities in the dependencies from your package.json.

Possible values are:

  • none
  • low
  • moderate
  • high
  • critical

With level none you disable the check completely.

example

Let's say you want to check only for vulnerabilities that have a priority level higher or equal to moderate.

Then if audit finds vulnerabilities with level lower than moderate, this extension will send a Slack message to channels with the npm audit report. And your build will continue.

If audit finds vulnerabilities with level higher or equal to moderate, then your build will break and you will still receive a Slack message.

If audit doesn't find any vulnerabilities, then you get no Slack message and your build will continue.

dev-level

This is the same as Level. But for the devDependencies from your package.json

workspace

The Slack workspace you use.

channels

A list with the Slack channels you want to send the reports with the result from npm audit.