gitman icon indicating copy to clipboard operation
gitman copied to clipboard

Gitman ignores groups on nested gitman install runs

Open jrisch opened this issue 4 years ago • 15 comments

We have just decided to switch from an inhouse developed, almost identical tool, to gitman. But I've stumbled across what seems to be a bug, during my initial testing:

Given a gitman.yml file that looks like this:

location: .gitman
sources:
  # Production sources
  - name: tf-module-production
    link: tf-module
    repo: git@githost:tf-module.git
    rev: 1.2.0
  # Dev sources
  - name: tf-module-dev
    link: tf-module
    repo: git@githost:tf-module.git
    rev: master
groups:
  - name: production
    members:
      - tf-module-production
  - name: dev
    members:
      - tf-module-dev

I expect that I end up with a directory looking like this, if I do a gitman install dev:

├── .gitman
├── .gitman.yml
└── tf-module -> .gitman/tf-module-dev

And if I do a gitman install production:

├── .gitman
├── .gitman.yml
└── tf-module -> .gitman/tf-module-production

This works - so far so good.

But if my tf-module contains a gitman.yml file with a similar structure and I run gitman install production, gitman actually installs all the sources, linking for each source, and it seems like I end up with the dev sources (so I end up with the master branches). I guess that gitman doesn't honour the groupname in the subsequent gitman install calls...?

jrisch avatar Aug 20 '20 08:08 jrisch

Thanks for the report!

if my tf-module contains a gitman.yml

By this do you mean that git@githost:tf-module.git has its own set of dependencies to be recursively managed by gitman? Could you share the output of that second gitman install production -vv run?

jacebrowning avatar Aug 20 '20 13:08 jacebrowning

Yes - sure! Here it is (some output is obfuscated):

[DEBUG   ] Running install command...
[INFO    ] Installing dependencies: production
[DEBUG   ] Searching for config...
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test
[DEBUG   ] Found config: /home/username/develop/gitman-test/.gitman.yml
[INFO    ] No locked sources, using latest...
[INFO    ] $ mkdir -p /home/username/develop/gitman-test/.gitman
[INFO    ] $ cd /home/username/develop/gitman-test/.gitman
[INFO    ] Updating source files...
[DEBUG   ] Creating a new repository...
[INFO    ] $ git clone --reference /home/username/.gitcache/gitman-subsub.reference [email protected]:username/gitman-subsub.git module-production
[DEBUG   ] > Cloning into 'module-production'...
[INFO    ] $ cd module-production
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production
[DEBUG   ] Confirming there are no uncommitted changes...
[DEBUG   ] $ git update-index -q --refresh
[DEBUG   ] $ git diff-index --quiet HEAD
[DEBUG   ] $ git ls-files --others --exclude-standard
[DEBUG   ] $ git rev-parse --abbrev-ref HEAD
[DEBUG   ] > master
[DEBUG   ] $ git rev-parse HEAD
[DEBUG   ] > fc6f3ed3c7f8ab297d22af0eda76e4bfd53d5676
[DEBUG   ] $ git describe --tags --exact-match
[DEBUG   ] > 0.0.1
[INFO    ] $ git remote set-url origin [email protected]:username/gitman-subsub.git
[INFO    ] $ git fetch --tags --force --prune origin 2.0.0
[DEBUG   ] > From githost.example:username/gitman-subsub
[DEBUG   ] > * tag               2.0.0      -> FETCH_HEAD
[DEBUG   ] $ git stash
[DEBUG   ] > No local changes to save
[INFO    ] $ git checkout --force 2.0.0
[DEBUG   ] > HEAD is now at fc6f3ed Update gitman.yml
[DEBUG   ] $ git branch --set-upstream-to origin/2.0.0
[DEBUG   ] > fatal: could not set upstream of HEAD to origin/2.0.0 when it does not point to any branch.
[DEBUG   ] Ignored error from call to 'git'
[INFO    ] Creating a symbolic link...
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production
[DEBUG   ] Found config: /home/username/develop/gitman-test/.gitman/module-production/gitman.yml
[INFO    ] No locked sources, using latest...
[INFO    ] $ mkdir -p /home/username/develop/gitman-test/.gitman/module-production/.gitman
[INFO    ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[INFO    ] Updating source files...
[DEBUG   ] Creating a new repository...
[INFO    ] $ git clone --reference /home/username/.gitcache/gitman-submodule.reference [email protected]:username/gitman-submodule.git module-production
[DEBUG   ] > Cloning into 'module-production'...
[INFO    ] $ cd module-production
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] Confirming there are no uncommitted changes...
[DEBUG   ] $ git update-index -q --refresh
[DEBUG   ] $ git diff-index --quiet HEAD
[DEBUG   ] $ git ls-files --others --exclude-standard
[DEBUG   ] $ git rev-parse --abbrev-ref HEAD
[DEBUG   ] > master
[DEBUG   ] $ git rev-parse HEAD
[DEBUG   ] > c2efb7cfb2766c8b67d0a027fa97b281ff4cea49
[DEBUG   ] $ git describe --tags --exact-match
[DEBUG   ] > fatal: no tag exactly matches 'c2efb7cfb2766c8b67d0a027fa97b281ff4cea49'
[DEBUG   ] Ignored error from call to 'git'
[INFO    ] $ git remote set-url origin [email protected]:username/gitman-submodule.git
[INFO    ] $ git fetch --tags --force --prune origin 1.0.0
[DEBUG   ] > From githost.example:username/gitman-submodule
[DEBUG   ] > * tag               1.0.0      -> FETCH_HEAD
[DEBUG   ] $ git stash
[DEBUG   ] > No local changes to save
[INFO    ] $ git checkout --force 1.0.0
[DEBUG   ] > HEAD is now at 8d84107 Release 1.0.0
[DEBUG   ] $ git branch --set-upstream-to origin/1.0.0
[DEBUG   ] > fatal: could not set upstream of HEAD to origin/1.0.0 when it does not point to any branch.
[DEBUG   ] Ignored error from call to 'git'
[INFO    ] Creating a symbolic link...
[INFO    ] $ mkdir -p /home/username/develop/gitman-test/.gitman/module-production/modules
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] No config found in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[INFO    ] Updating source files...
[DEBUG   ] Creating a new repository...
[INFO    ] $ git clone --reference /home/username/.gitcache/gitman-submodule.reference [email protected]:username/gitman-submodule.git module-sandbox
[DEBUG   ] > Cloning into 'module-sandbox'...
[INFO    ] $ cd module-sandbox
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] Confirming there are no uncommitted changes...
[DEBUG   ] $ git update-index -q --refresh
[DEBUG   ] $ git diff-index --quiet HEAD
[DEBUG   ] $ git ls-files --others --exclude-standard
[DEBUG   ] $ git rev-parse --abbrev-ref HEAD
[DEBUG   ] > master
[DEBUG   ] $ git rev-parse HEAD
[DEBUG   ] > c2efb7cfb2766c8b67d0a027fa97b281ff4cea49
[DEBUG   ] $ git describe --tags --exact-match
[DEBUG   ] > fatal: no tag exactly matches 'c2efb7cfb2766c8b67d0a027fa97b281ff4cea49'
[DEBUG   ] Ignored error from call to 'git'
[DEBUG   ] $ git stash
[DEBUG   ] > No local changes to save
[INFO    ] $ git checkout --force master
[DEBUG   ] > Already on 'master'
[DEBUG   ] > Your branch is up to date with 'origin/master'.
[DEBUG   ] $ git branch --set-upstream-to origin/master
[DEBUG   ] > Branch 'master' set up to track remote branch 'master' from 'origin'.
[INFO    ] Creating a symbolic link...
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] No config found in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman
[INFO    ] Skipped dependency: module-sandbox
[INFO    ] No locked sources, using latest...
[INFO    ] $ cd /home/username/develop/gitman-test/.gitman
[INFO    ] Running install scripts...
[INFO    ] $ cd module-production
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production
[INFO    ] (no scripts to run)
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production
[DEBUG   ] Found config: /home/username/develop/gitman-test/.gitman/module-production/gitman.yml
[INFO    ] No locked sources, using latest...
[INFO    ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[INFO    ] Running install scripts...
[INFO    ] $ cd module-production
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[INFO    ] (no scripts to run)
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] No config found in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-production
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[INFO    ] Running install scripts...
[INFO    ] $ cd module-sandbox
[DEBUG   ] Checking for a valid working tree...
[DEBUG   ] $ git rev-parse --is-inside-work-tree
[DEBUG   ] > true
[DEBUG   ] Checking for a valid git top level...
[DEBUG   ] $ git rev-parse --show-toplevel
[DEBUG   ] > /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] $ cwd /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[INFO    ] (no scripts to run)
[DEBUG   ] Looking for config in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] No config found in: /home/username/develop/gitman-test/.gitman/module-production/.gitman/module-sandbox
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman/module-production/.gitman
[DEBUG   ] $ cd /home/username/develop/gitman-test/.gitman
[INFO    ] Installed 3 dependencies
[DEBUG   ] Command succeeded

The config looks like this:

location: .gitman
sources:
  - name: module-production
    repo: [email protected]:username/gitman-subsub.git
    rev: 2.0.0
    link: modules/module0
  - name: module-sandbox
    repo: [email protected]:username/gitman-subsub.git
    rev: master
    link: modules/module0
groups:
    - name: production
      members:
          - module-production
    - name: sandbox
      members:
          - module-sandbox

jrisch avatar Aug 20 '20 13:08 jrisch

Does gitman-subsub.git have it's own gitman config file? Can you share that as well?

jacebrowning avatar Aug 20 '20 14:08 jacebrowning

Yes, sure:

location: .gitman
sources:
  # Production sources
  - name: module-production
    link: modules/module1
    repo: [email protected]:username/gitman-submodule.git
    rev: 1.0.0
  # Dev sources
  - name: module-sandbox
    link: modules/module1
    repo: [email protected]:username/gitman-submodule.git
    rev: master
groups:
  - name: production
    members:
      - module-production
  - name: sandbox
    members:
      - module-sandbox

jrisch avatar Aug 20 '20 14:08 jrisch

Thanks, that's helpful! You're correct that groups are only processed once at the top level, so I believe this issue is a request to pass that information to each nested level.


FWIW, I'm not sure if installing different versions of the same dependency is the intended use case for groups.

You should be able to accomplish what you're trying to do with locked sources: https://gitman.readthedocs.io/en/latest/use-cases/branch-tracking/

location: .gitman
sources:
  - name: module-production
    repo: [email protected]:username/gitman-subsub.git
    rev: master
    link: modules/module0
sources_locked:
  - name: module-production
    repo: [email protected]:username/gitman-subsub.git
    rev: 2.0.0
    link: modules/module0

where your "dev" setup is gitman update --skip-lock and your "production" setup is gitman install.

jacebrowning avatar Aug 20 '20 14:08 jacebrowning

Hi Jace

Thank you for your answer. You’re right that I can used locked_sources for that simple example. Truth is that I have 3 environments - production, preprod and prod - which requires the group functionality, together with different named versions of the same sources. You could probably argue that I could/should use locked_sources for both preprod and prod, but it would be nice to differentiate those two, until I feel confident that the version is ready for production.

Do you have any idea if it can be implemented..? I took a look at the code yesterday, but I can’t seem to find where it descends into the sub repo and calls itself again..

(As a side note: I use this for a Infrastructure As Code repo, where the sources that Gilman is managing, is the terraform modules and sub modules used for managing the infrastructure. So I can have situations where I’m doing a new release of the infrastructure, but still need to be able to ensure that the production environment is running the current version (be able to run terraform plan without seeing any changes). Unfortunately, our in-house tool is having the same exact ‘bug’ (not honoring the groups in the sub repos) :-( - together with other bugs ).

Sent from my iPad

On 20 Aug 2020, at 16.46, Jace Browning [email protected] wrote:

 Thanks, that's helpful! You're correct that groups are only processed once at the top level, so I believe this issue is a request to pass that information to each nested level.

FWIW, I'm not sure if installing different versions of the same dependency is the intended use case for groups.

You should be able to accomplish what you're trying to do with locked sources: https://gitman.readthedocs.io/en/latest/use-cases/branch-tracking/

location: .gitman sources:

  • name: module-production repo: [email protected]:username/gitman-subsub.git rev: master link: modules/module0 sources_locked:
  • name: module-production repo: [email protected]:username/gitman-subsub.git rev: 2.0.0 link: modules/module0 where your "dev" setup is gitman update --skip-lock and your "production" setup is gitman install.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

jrisch avatar Aug 21 '20 05:08 jrisch

This is the spot where "production" is translated to ["tf-module-production"]: https://github.com/jacebrowning/gitman/blob/5acc0e4b1d5c15683213563901acd0349a1fa155/gitman/models/config.py#L87

This is the spot where we recurse into nested repositories: https://github.com/jacebrowning/gitman/blob/5acc0e4b1d5c15683213563901acd0349a1fa155/gitman/models/config.py#L117

You'll notice that names are not forwarded to recursive installation calls. To achieve the behavior you're looking for, we would need to determine that "production" is the name of a group (and not just the name of a single source), then forward that as *names to all recursive calls. In hindsight, having a separate --groups argument may have been a better design to keep these lists of names separate.

Another thing to consider is how to handle nested gitman configs that don't have groups defined, but are passed a group name.

jacebrowning avatar Aug 21 '20 14:08 jacebrowning

Hi Jace

Thank you for the pointers - I’ll have a look at it.

Gitman files without groups: Maybe just treat that as a normal gitman install, and install the repos listed under sources...?

On 21 Aug 2020, at 16.55, Jace Browning [email protected] wrote:

 This is the spot where "production" is translated to ["tf-module-production"]: https://github.com/jacebrowning/gitman/blob/5acc0e4b1d5c15683213563901acd0349a1fa155/gitman/models/config.py#L87

This is the spot where we recurse into nested repositories: https://github.com/jacebrowning/gitman/blob/5acc0e4b1d5c15683213563901acd0349a1fa155/gitman/models/config.py#L117

You'll notice that names are not forwarded to recursive installation calls. To achieve the behavior you're looking for, we would need to determine that "production" is the name of a group (and not just the name of a single source), then forward that as *names to all recursive calls. In hindsight, having a separate --groups argument may have been a better design to keep these lists of names separate.

Another thing to consider is how to handle nested gitman configs that don't have groups defined, but are passed a group name.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

jrisch avatar Aug 24 '20 05:08 jrisch

We have a similar requirement solved by using seperate branches in the top level repository (like dev and prod) to maintain seperate gitman configs because of our many repositories and parallel dev enviroments. Switching between environments is just accomblished by switching between branches.

Furthermore we realized that the recursive dependency resolution increases the complexity of the config management at a certain amount of nested dependency levels. We have a very complex dependency graph with more than 80 repositories. To simplify the config management we introduced a distinct top level "product" repository which contains one huge flat gitman.yml and some product related global stuff (configs/build scripts/jenkins groovy scripts). We don't use recursive dependency resolution which can also produce hard to find problems when referencing different versions of the same repository.

We resolve all product related dependencies over a global gitman config. Each developer and also our build system needs to use this product repository to build all or parts of the product. This helps to avoid workspace clashes. Because of the many different software developer roles resp. software modules we defined groups which represents sub-workspaces (like app_a, app_b, hal, drivers and so on). This works quite well.

In a release phase we create a new release branch in this toplevel repository and pining each of the dependencies one by one. At the end in each rev-field is a tag referenced. To see what changed over several releases or between dev activities is quite easy by comparing the one and only gitman.yml between the different branches,

Maybe this approach is also helpful for your application.

daniel-brosche avatar Aug 24 '20 10:08 daniel-brosche

@daniel-brosche Thank you for your input - although I have a hard time figuring out what you are doing. Can you maybe paint the picture a little bit clearer with a simple example..?

jrisch avatar Aug 24 '20 12:08 jrisch

Maybe this helps, I have tried to illustrate it with an abstract example.

The product repository here is product_xy which contains the global product related gitman.yml besides some other stuff.

Mostly we continously build the mainline (master) of all repositories during the common development phase. Here the product repository master branch references the needed master branches of all repository dependencies. As mentioned, this product repository is used by all developers and the buildsystem itself (jenkins here).

image

In this global gitman.yml there are groups defined which represents sub-workspaces for the main developer domains.

In the release phase I create a release branch in the product repository and reference tags over time. At the end of stabilization only tags are referenced in this product repository release branch.

image

For very complex features I mix these approaches and create a distinct development environment that reference feature branches and tags.

image

Over this way, I can ensure a stable feature environment where only the related feature repositories are mutable over time (e.g. 75% of all repositories are immutable and 25% are mutable).

This is also very helpful to exchange feature related workspaces between developers and buildsystem to build reproducible feature related builds. At the end of the feature development all depedent feature repositories are merged in the corresponding master branch and the feature branch in the toplevel repository will be deleted.

Some parts of this worklow can also be achieved by locking sources but in my experience this approach is more explicit and pretty easy in terms of config management.

daniel-brosche avatar Aug 24 '20 20:08 daniel-brosche

This is almost how I do it. I have a directory structure like this one:

tf-live/
├── gitman.yml
├── tf-bootstrap
│   └── modules
│       └── tf-aws
├── tf-network
│   ├── gitman.yml
│   └── modules
│       ├── tf-asg
│       └── tf-aws-network
│           └── modules
│               └── tf-vpn-gateway
└── tf-services
    └── modules
        └── tf-aws-service

tf-live is just a shell, containing a gitman.yml file and a script to wrap the calls to terraform in the right order. I have 3 environments, sandbox, preprod and prod. I want the toplevel gitman.yml file to check out the same tf-* repos, but it different versions, depending on the environment:

tf-live/
├── gitman.yml
├── tf-bootstrap 
├── tf-network
└── tf-services
  • Master branch, when it's sandbox
  • v1.0.0 if it's production
  • v1.1.0if it's preprod and I'm testing a new release

I was hoping that groups could do that for me, and it works fine in the top level. But when fx tf-network contains modules, these can also vary depending on the environment. And they can also have submodules, with differing versions depending on the environment (which means another gitman.yml file):

tf-live/tf-network/
├── gitman.yml
└── modules
    ├── tf-asg
    └── tf-aws-network
        ├── gitman.yml
        └── modules
            └── tf-vpn-gateway

If gitman supported sending the groupname to the subsequent gitman install command, it would work fine, but it doesn't.

Unfortunately I'm not a python programmer, so I'm not exactly sure how to solve this in the code, but I'll try to take a stab at it.

I might end up using a dedicated wrapper tool like terragrunt for this instead, as it handles environments with dependencies of differing versions just fine. But we also use this functionality in other code projects, and would like to use gitman if at all possible...

jrisch avatar Aug 25 '20 12:08 jrisch

Just a quick thought: Would it be possible/nice to structure the config as follows, instead of the separate groups section?:

location: .gitman
sources:
  default:
    # Production sources
    - name: tf-module-production
      link: tf-module
      repo: git@githost:tf-module.git
      rev: 1.2.0
  dev:
    # Dev sources
    - name: tf-module-dev
      link: tf-module
      repo: git@githost:tf-module.git
      rev: master

Then always have a default "group" or section, which get's installed when just running gitman install.

jrisch avatar Aug 25 '20 12:08 jrisch

But when fx tf-network contains modules, these can also vary depending on the environment.

According to my described approach, there is no nested gitman.yml and then I would arrange it like this:

In the master Branch of tv-life:

location: .gitman
sources:
  - name: module0
    repo: [email protected]:username/gitman-subsub.git
    rev: master
    link: modules/module0
  - name: module1
    link: modules/module1
    repo: [email protected]:username/gitman-submodule.git
    rev: master

In the branch v1.0.0

location: .gitman
sources:
  - name: module0
    repo: [email protected]:username/gitman-subsub.git
    rev: 2.0.0
    link: modules/module0
 - name: module1
    link: modules/module1
    repo: [email protected]:username/gitman-submodule.git
    rev: 1.0.0

You could also change the gitman location to modules then the links are not needed.

I do import everything in defined imports directory also with subdirectories like infra\component1 directly over the name field (-name: infra/component1). All components look into this directory to resolve their own dependencies (by convention).

daniel-brosche avatar Aug 26 '20 07:08 daniel-brosche

I've come up with an alternative approach that I like a bit better.

First we add a gitman config file for each environment:

gitman-production.yml gitman-preprod.yml gitman-sandbox.yml

Then a simple Makefile:

.PHONY: install clean uninstall

all: .gitman.yml
  @echo "Preparing for deploying to ${ENV}..."
  gitman install

.gitman.yml::
  @ln -sf gitman-${ENV}.yml .gitman.yml

clean:
  gitman uninstall --force
  -rm -f .gitman.yml

uninstall:
  gitman uninstall
  -rm -f .gitman.yml

All it does is symlinking the gitman-${ENV}.yml file to .gitman.yml and run gitman install (besides the clean and uninstall targets)

In all subrepos we add a similar structure (if it has dependencies on anything, of course):

gitman-production.yml gitman-preprod.yml gitman-sandbox.yml Makefile

Each gitman-env.yml file looks like this (with multiple different repos in different revisions of course):

location: .gitman
sources:
  - name: testhest
    repo: [email protected]:username/gitman-test.git
    rev: master
    link: testhest
    scripts:
      - ENV=${ENV} make

As you can see it runs make in the end, with the $ENV var preprended. This makes the sub repos’ git install command use the correct gitman config file. The .gitman.yml (which is just a symlink) should be ignored in .gitignore.

So to sum it up: With a setup like this, we have a workflow looking like this (deploying to production):

  1. Check out main repo
  2. Run ENV=production make to install production sources
  3. Run deployment scripts
  4. Run make clean to clean up (this forces a gitman uninstall)

jrisch avatar Sep 09 '20 08:09 jrisch