concourse / semver-resource

automated semantic version bumping
Apache License 2.0
97 stars 105 forks source link

Semver Resource

A resource for managing a version number. Persists the version number in one of several backing stores.

Source Configuration

There are four supported drivers, with their own sets of properties for configuring them.

git Driver

The git driver works by modifying a file in a repository with every bump. The git driver has the advantage of being able to do atomic updates.

s3 Driver

The s3 driver works by modifying a file in an S3 compatible bucket.

swift Driver

The swift driver works by modifying a file in a container.

gcs Driver

The gcs driver works by modifying a file in a Google Cloud Storage bucket.

Example

With the following resource configuration:

resources:
- name: version
  type: semver
  source:
    driver: git
    uri: git@github.com:concourse/concourse.git
    branch: version
    file: version
    private_key: {{concourse-repo-private-key}}

Bumping with a get and then a put:

plan:
- get: version
  params: {bump: minor}
- task: a-thing-that-needs-a-version
- put: version
  params: {file: version/version}

Or, bumping with an atomic put:

plan:
- put: version
  params: {bump: minor}
- task: a-thing-that-needs-a-version

Behavior

check: Report the current version number.

Detects new versions by reading the file from the specified source. If the file is empty, it returns the initial_version. If the file is not empty, it returns the version specified in the file.

in: Provide the version as a file, optionally bumping it.

Provides the version number to the build as a version file in the destination.

Can be configured to bump the version locally, which can be useful for getting the final version ahead of time when building artifacts.

Parameters

Note that bump and pre don't update the version resource - they just modify the version that gets provided to the build. An output must be explicitly specified to actually update the version.

out: Set the version or bump the current one.

Given a file, use its contents to update the version. Or, given a bump strategy, bump whatever the current version is. If there is no current version, the bump will be based on initial_version.

The file parameter should be used if you have a particular version that you want to force the current version to be. This can be used in combination with in, but it's probably better to use the bump and pre params as they'll perform an atomic in-place bump if possible with the driver.

Parameters

One of the following must be specified:

When bump and/or pre are used, the version bump will be applied atomically, if the driver supports it. That is, if we pull down version N, and bump to N+1, the driver can then compare-and-swap. If the compare-and-swap fails because there's some new version M, the driver will re-apply the bump to get M+1, and try again (in a loop).

Version Bumping Semantics

Both in and out support bumping the version semantically via two params: bump and pre:

Check-less Usage

A classic usage of semver resource is like:

resources:
- name: version
  type: semver
  source:
    driver: git
    uri: git@github.com:concourse/concourse.git
    branch: version
    file: version
    private_key: {{concourse-repo-private-key}}

jobs:
- name: some-job
  plan:
  - get: trigger-resource
    trigger: true
  - get: version
    param: {bump: major}
  - task: a-thing-that-needs-a-version
  - put: version
    params: {file: version/version}

In above classic mode, Concourse will run periodic checks against the semver resource version. Each check will do a git clone as the driver is git. When there are a lot of semver resources, checks on semver resources may also bring burden to the git system as each check will invoke a git clone.

Given each semver resource requires a parameter file in source, semver resources are hard to enjoy benefits of global resources.

To mitigate the burden of checks, if a semver resource is not a job trigger, check-less mode can be used. The above sample then can be rewritten as:

jobs:
- name: some-job
  plan:
  - get: trigger-resource
    trigger: true
  - put: version # change `get` to `put`
    params:
      get_latest: true # and set `get_latest: true`
      bump: major
  - task: a-thing-that-needs-a-version
  - put: version
    params: {file: version/version}

You may have noticed that, original get: version is changed to put: version. Now resource version is put-only, then Concourse will no longer run check on it. Param get_latest: true tells the put step to only fetch the latest version without bumping anything. Then the implied get will fetch a version as a typical get step.

If your Concourse or Git (e.g. Gitlab) systems are exhausted by semver resources' checks, you may consider reforming pipelines to use this check-less usage.

The cons of check-less usage are:

Running the tests

The tests have been embedded with the Dockerfile; ensuring that the testing environment is consistent across any docker enabled platform. When the docker image builds, the test are run inside the docker container, on failure they will stop the build.

Run the tests with the following command:

docker build -t semver-resource --target tests --build-arg base_image=paketobuildpacks/run-jammy-base:latest .

Integration tests

The integration requires two AWS S3 buckets, one without versioning and another with. The docker build step requires setting --build-args so the integration will run.

You will need:

Run the tests with the following command, replacing each build-arg value with your own values:

docker build . -t semver-resource --target tests -f dockerfiles/alpine/Dockerfile \
  --build-arg SEMVER_TESTING_ACCESS_KEY_ID="some-key" \
  --build-arg SEMVER_TESTING_SECRET_ACCESS_KEY="some-secret" \
  --build-arg SEMVER_TESTING_BUCKET="some-bucket" \
  --build-arg SEMVER_TESTING_REGION="some-region"

docker build . -t semver-resource --target tests -f dockerfiles/ubuntu/Dockerfile \
  --build-arg SEMVER_TESTING_ACCESS_KEY_ID="some-key" \
  --build-arg SEMVER_TESTING_SECRET_ACCESS_KEY="some-secret" \
  --build-arg SEMVER_TESTING_BUCKET="some-bucket" \
  --build-arg SEMVER_TESTING_REGION="some-region"

Contributing

Please make all pull requests to the master branch and ensure tests pass locally.