I’ve been tasked with implementing a GIT workflow and also a release management process.
I’ve been looking into DataOps and this implementation seems to match what was requested to me.
The key points are:
- Need 4 stable branches: main, staging, test and dev.
- Need to be able to work on features completely independent. What I mean is that, if my coworker is working on feature001 and I’m working on feature002, then neither of the features should have to wait for the other feature in order to go to the higher environments.
However, something that I don’t understand is happening.
So far in my tests, these are the steps I took:
- I created a feature branch called feature/name001 where I create a file called text001.txt.
Then I push to the higher environments:
- feature001 -> dev
- feature001 -> qa
- I create a 2nd feature branch called feature/name002 where I create a file called text002.txt.
Similarly:
- feature002 -> dev
- feature002 -> qa
- feature002 -> staging
- Created a hotfix branch called hotfix/bug001 where I create a file called hotfix001.txt.
- hotfix001 -> main
- I then did a PR from staging -> main. This merged the file text002.txt to main.
- feature001 -> staging
- I then did a PR from staging -> main. This merged the file text001.txt to main.
- I create a 3rd feature branch called feature/name003 where I store the existing files (text001.txt, text002.txt) in a new folder called texts.
- feature003 -> dev
Here is where I see the issue.
I expected my dev environment to look something like this:
texts/text001.txt
texts/text002.txt
hotfix001.txt
Instead, this is what I see:
texts/text001.txt
texts/text002.txt
text001.txt
hotfix001.txt
Any idea on why this is happening?
Below is the python script I’m using to test this out. This script was made in 30min, so it’s not in it’s production stage at all!
# %%
import subprocess
import argparse
# %%
def create_feature_branch(branch_name: str):
"""
Fetches updates, creates a new feature branch from origin/main and checks it out.
Arguments:
branch_name : Name of feature branch to create.
message : Initial commit message for feature branch creation.
"""
try:
subprocess.run(["git", "checkout", "main"])
except e:
Exception("Something went switching to main", e)
try:
subprocess.run(["git", "pull", "--rebase", "origin", "main"])
except e:
Exception("Something went wrong when rebasing from origin/main", e)
try:
subprocess.run(["git", "checkout", "-b", branch_name])
except e:
Exception("Something went creating new branch", e)
# %%
def deploy_to_environment(branch_name, env_branch):
"""
Rebase feature branch from origin/main.
Merges feature branch to specified env_branch.
Pushes to origin/env_branch.
Arguments:
branch_name : Name of feature branch to be deployed.
env_branch : Name of base branch.
"""
subprocess.run(["git", "checkout", branch_name])
subprocess.run(["git", "pull", "--rebase", "origin", "main"])
subprocess.run(["git", "checkout", env_branch])
subprocess.run(["git", "pull", "--rebase", "origin", env_branch])
subprocess.run(["git", "merge", branch_name])
subprocess.run(["git", "push", "origin", env_branch])
# %%
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Automate GIT Release Workflow.")
parser.add_argument("branch_name", type=str, help="Name of the feature branch.")
deployment_environment = parser.add_mutually_exclusive_group(required=False)
deployment_environment.add_argument(
"--d",
"--dev",
"--deploy-dev",
action="store_true",
help="Deploy to dev branch.",
)
deployment_environment.add_argument(
"--t",
"--tst",
"--deploy-tst",
action="store_true",
help="Deploy to tst branch.",
)
deployment_environment.add_argument(
"--s",
"--stg",
"--deploy-stg",
action="store_true",
help="Deploy to stg branch.",
)
deployment_environment.add_argument(
"--p",
"--prd",
"--deploy-prd",
action="store_true",
help="Deploy to prd branch.",
)
args = parser.parse_args()
if not (args.d or args.t or args.s or args.p):
create_feature_branch(args.branch_name)
print("Created and switched to branch", args.branch_name)
else:
if args.d:
deploy_to_environment(args.branch_name, "dev")
print("Deployed", args.branch_name, "to dev environment.")
if args.t:
deploy_to_environment(args.branch_name, "test")
print("Deployed", args.branch_name, "to tst environment.")
if args.s:
deploy_to_environment(args.branch_name, "staging")
print("Deployed", args.branch_name, "to stg environment.")
if args.p:
deploy_to_environment(args.branch_name, "main")
print("Deployed", args.branch_name, "to prd environment.")