Gino Keva works as a simple Key Value store built on top of Git Notes, using an event sourcing architecture.
- Events are added to the current commit when manipulating key/values via get or unset actions
- Gino Keva compiles a snapshot of all historical key/values by replaying all events up to the current commit
Although Gino Keva was written with the below use case in mind, it intends to be a generic tool. Don't get discouraged if your intended use is very different. Instead feel free to open a ticket, so we can discuss if we can make it work.
The need for Gino Keva was born in an environment where ~20 components (some would call micro-services) live together in a single repository. Every component is deployed in a docker container; together they form an application/service. There's a single build pipeline that triggers upon any change. The pipeline will then fan out and trigger an independent build (and test) for each component impacted by the change. For each component, this results in a new docker container which is versioned and pushed to the registry. Once all components are rebuilt, the set of containers (of which some newly built) can be deployed and tested and eventually be promoted to production.
Due to the selective build mechanism, the versions of components are not coupled. Some will rarely change, others frequently. Now how to keep track of the set of containers that make up the application? It makes sense to keep this build metadata inside the version control system, so we have it available for each commit that was built. But we'd hate to see the build pipeline polluting the git history with artificial commits. This is where Gino Keva was born.
Gino Keva is used to store the newly built version of any component as a key/value pair in git notes, linked to commit it was built from: COMPONENT_foo=1.1.0
.
For each deployment, the list of containers which make up the application is simply collected based on the output of gino-keva list
:
Before | After |
---|---|
COMPONENT_foo=1.0.0 | COMPONENT_foo=1.1.0 (updated) |
COMPONENT_BAR=1.2.3 | COMPONENT_BAR=1.2.3 (untouched) |
.... | .... |
- Git CLI: Gino Keva uses the git CLI as installed on the host. Tested with version 2.32.0, however any recent version should do.
See below examples on how to use gino-keva, or run gino-keva --help
for help.
By default, gino-keva will not push your changes to the upstream. You likely would like to change this behaviour by specifying --push
, or setting the environment variable GINO_KEVA_PUSH=1
.
If you do not do this, subsequent fetches will overwrite any local changes made.
foo@bar (f10b970d):~$ gino-keva set key my_value
foo@bar (f10b970d):~$ gino-keva set counter 12
foo@bar (f10b970d):~$ gino-keva set foo bar
foo@bar (f10b970d):~$ gino-keva list
counter=12
foo=bar
key=my_value
foo@bar (f10b970d):$ git commit --allow-empty -m "Dummy commit"
foo@bar (a8517558):$ gino-keva set pi 3.14
foo@bar (a8517558):~$ gino-keva list --output=json
{
"counter": "12",
"foo": "bar",
"key": "my_value",
"pi": "3.14"
}
### Unset keys
Finally, you can unset keys using `unset`:
```console
foo@bar (a8517558):~$ gino-keva unset foo
foo@bar (a8517558):~$ gino-keva list
counter=12
key=my_value
pi=3.14
By default the notes are saved to refs/notes/gino-keva
, but this can be changed with the --ref
command-line switch. To store your key/value under refs/notes/banana
:
foo@bar (a8517558):~$ gino-keva --ref=banana set color yellow
Since Gino Keva simply uses the git CLI, you can use (most of) the options it provides to set/override the configuration. You could either use git config
to setup the system is desired, or use environment variables to achieve the same.
Example: Add a key/value pair as the "whatever <[email protected]>" user
GIT_CONFIG_COUNT=2 \
GIT_CONFIG_KEY_0="user.name" GIT_CONFIG_VALUE_0="whatever" \
GIT_CONFIG_KEY_1="user.email" GIT_CONFIG_VALUE_1="[email protected]" \
gino-keva set foo bar
Gino Keva supports just simple key=value
format (default), or json (--output=json
). However, you can parse the output in any format you'd like.
Example: Use gino-keva as part of a GitHub action:
foo@bar:~$ gino-keva list | awk -F= '{print "::set-output name="$1"::"$2}'
::set-output name=COUNTER::12
::set-output name=key::my_value
::set-output name=PI::3.14
Example: Use gino-keva as part of an Azure Devops pipeline:
foo@bar:~$ gino-keva list | awk -F= '{print "##vso[task.setvariable variable="$1"]"$2}'
##vso[task.setvariable variable=COUNTER]12
##vso[task.setvariable variable=key]my_value
##vso[task.setvariable variable=PI]3.14