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 byactions/checkout
- Records lock and unlock histories
- Supports waiting until a lock is released
How to Use
This action requires two inputs:key
andmode
.
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 lockunlock
: Releases a lockcheck
: Checks the lock status
mode: lock
:
steps:-name:Acquire a lock for a key `foo` before deploying an applicationuses:suzuki-shunsuke/lock-action@latestwith:mode:lockkey:foo-run:bash deploy.sh foo
mode: unlock
:
steps:-name:Release a lockuses:suzuki-shunsuke/lock-action@latestwith:mode:unlockkey:foo
mode: check
:
steps:-name:Check if a key is being lockedid:checkuses:suzuki-shunsuke/lock-action@latestwith:mode:checkkey:foo-run:bash deploy.sh fooif:steps.check.outputs.already_locked != 'true'
You can also usepost_unlock: "true"
to release a lock automatically in a post step.
-uses:suzuki-shunsuke/lock-action@latestwith:mode:lockkey:foopost_unlock:"true"
By default,mode: lock
will fail if the key is already locked.
Setignore_already_locked_error: "true"
to avoid this.
-uses:suzuki-shunsuke/lock-action@latestwith:key:foomode:lockignore_already_locked_error:"true"
To forcemode: check
to fail if a key is locked, usefail_if_locked: "true"
.
# This step fails if the key `foo` is being locked.-uses:suzuki-shunsuke/lock-action@latestwith:mode:checkkey:foofail_if_locked:"true"
To wait until a lock is released, usemax_wait_seconds
andwait_interval_seconds
.
-uses:suzuki-shunsuke/lock-action@latestwith:mode:lockkey: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 formode: check
.
-uses:suzuki-shunsuke/lock-action@latestwith:mode:checkkey:default# Check a lock every 5 seconds until the lock is released or 60 seconds passmax_wait_seconds:"30"wait_interval_seconds:"5"
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 withkey_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.
Example links:
Conclusion
In this post, I introduced my GitHub Action for a lock mechanism. For more details, please visit the repository:
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse