Home

Awesome

lock-action

GitHub Action for lock mechanism using GitHub branches

Lock Mechanism is useful in CI workflows, like when you need to prevent simultaneous deployments or block deployments during maintenance.

Features

How to use

This action requires two inputs: key and mode.

mode: lock:

steps:
  - name: Acquire a lock for a key `foo` before deploying an application
    uses: suzuki-shunsuke/lock-action@latest
    with:
      mode: lock
      key: foo
  - run: bash deploy.sh foo

mode: unlock:

steps:
  - name: Release a lock
    uses: suzuki-shunsuke/lock-action@latest
    with:
      mode: unlock
      key: foo

mode: check:

steps:
  - name: Check if a key is being locked
    id: check
    uses: suzuki-shunsuke/lock-action@latest
    with:
      mode: check
      key: foo
  - run: bash deploy.sh foo
    if: steps.check.outputs.locked != 'true'

You can also use post_unlock: "true" to release a lock automatically in a post step.

- uses: suzuki-shunsuke/lock-action@latest
  with:
    mode: lock
    key: foo
    post_unlock: "true"

By default, mode: lock will fail if the key is already locked. Set ignore_already_locked_error: "true" to avoid this.

- uses: suzuki-shunsuke/lock-action@latest
  with:
    key: foo
    mode: lock
    ignore_already_locked_error: "true"

To force mode: check to fail if a key is locked, use fail_if_locked: "true".

# This step fails if the key `foo` is being locked.
- uses: suzuki-shunsuke/lock-action@latest
  with:
    mode: check
    key: foo
    fail_if_locked: "true"

To wait until a lock is released, use max_wait_seconds and wait_interval_seconds.

- uses: suzuki-shunsuke/lock-action@latest
  with:
    mode: lock
    key: default
    # Try to acquire a lock every 10 seconds until acquiring a lock or 60 seconds pass.
    max_wait_seconds: "60"
    wait_interval_seconds: "10"

These inputs are also available for mode: check.

- uses: suzuki-shunsuke/lock-action@latest
  with:
    mode: check
    key: default
    # Check a lock every 5 seconds until the lock is released or 60 seconds pass
    max_wait_seconds: "30"
    wait_interval_seconds: "5"

#131 #135 >= v0.1.4 You can check if this action can acquire the lock in later jobs using the output locked. The output is useful if you want to release a lock in a later job.

lock:
  runs-on: ubuntu-latest
  permissions:
    contents: write
  outputs:
    locked: ${{steps.lock.outputs.locked}}
  steps:
    - uses: suzuki-shunsuke/lock-action@c752be910ac812e0adc50316855416514d364b57 # v0.1.3
      id: lock
      with:
        mode: lock
        key: dev
    # ...

unlock:
  runs-on: ubuntu-latest
  needs: lock
  permissions:
    contents: write
  steps:
    - uses: suzuki-shunsuke/lock-action@c752be910ac812e0adc50316855416514d364b57 # v0.1.3
      if: needs.lock.outputs.locked == 'true'
      with:
        mode: unlock
        key: dev

Available versions

[!CAUTION] We don't add dist/*.js in the main branch and feature branches. So you can't specify main and feature branches as versions.

# This never works as dist/index.js doesn't exist.
uses: suzuki-shunsuke/lock-action@main

The following versions are available.

  1. Release versions
uses: suzuki-shunsuke/lock-action@v0.1.1
  1. Pull Request versions: These versions are removed when we feel unnecessary. These versions are used to test pull requests.
uses: suzuki-shunsuke/lock-action@pr/37
  1. latest branch: This branch is built by CI when the main branch is updated. Note that we push commits to the latest branch forcibly.
uses: suzuki-shunsuke/lock-action@latest

Pull Request versions and the latest branch are unstable. These versions are for testing. You should use the latest release version in production.

Example

We provide an example workflow (code) via workflow_dispatch. To try this, please fork this repository or copy the workflow.

  1. lock: Lock the given key
  2. unlock: Unlock the given key
  3. check: Check if the key is being locked
  4. terraform_plan: Check if the key is being locked before running terraform plan. The job would fail if the key is being locked.
  5. terraform_apply: Lock the key for 120 seconds and release the lock. The job would fail if the key is being locked.

How It Works

This action manages locks by creating and updating GitHub branches. Each lock’s state is tracked in the commit message of a branch named ${{inputs.key_prefix}}${{inputs.key}} (default prefix: lock__, which can be customized with key_prefix).

Commit message format:

unlock by suzuki-shunsuke: test
{
  "message": "test",
  "state": "unlock",
  "actor": "suzuki-shunsuke",
  "github_actions_workflow_run_url": "https://github.com/suzuki-shunsuke/test-github-action/actions/runs/11545637203?pr=237",
  "pull_request_number": 237
}

From these commit messages, you can see when and who (actor, workflow run, pull request number) acquired or released the lock.

commits

commit message

Example links:

Inputs / Outputs

Please see action.yaml

Restriction of key_prefix and key inputs

This action creates branches ${{inputs.key_prefix}}${{inputs.key}}, so ${{inputs.key_prefix}}${{inputs.key}} must follow the rule of Git and GitHub branches.

LICENSE

MIT