DEV Community

Shunsuke Suzuki
Shunsuke Suzuki

Posted on

Lock Mechanism on GitHub Actions

Sometimes, a lock mechanism is useful in CI workflows, like when you need to prevent simultaneous deployments or block deployments during maintenance.
In this post, I’ll introduce a GitHub Action for implementing a lock mechanism.

https://github.com/suzuki-shunsuke/lock-action

Features

  • No dependencies on external services like AWS or GCP
  • No reliance on shell or external commands such as git
  • Achieves locking using GitHub branches
  • Manage branches via GitHub API without git command. You don't have to checkout repositories by actions/checkout
  • Records lock and unlock histories
  • Supports waiting until a lock is released

How to Use

This action requires two inputs: key and mode.

  • key: an explicit identifier for the lock, which you can adjust by service and environment.
  • mode: the action’s operational mode, which can be one of these:
    • lock: Acquires a lock
    • unlock: Releases a lock
    • check: Checks the lock status

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
Enter fullscreen mode Exit fullscreen mode

mode: unlock:

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

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.already_locked != 'true'
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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:

Conclusion

In this post, I introduced my GitHub Action for a lock mechanism. For more details, please visit the repository:

https://github.com/suzuki-shunsuke/lock-action

Top comments (0)