PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, September 27, 2022

[FIXED] How to get a git diff so I can use it to bump my version with semver? (ThreeDotLabs Tutorial)

 September 27, 2022     continuous-deployment, continuous-integration, git, python     No comments   

Issue

I have used the Tutorial from ThreeDotsLab to create my automated versioning for my CI/CD pipeline in git (the pipeline builds debian packages and delivers them to my server).

I have already tried various answers from posts like this question. Maybe I am just too stupid to get this right but this is what my code looks like right now:

#!/usr/bin/env python3
#automatic versioning like explained in https://threedots.tech/post/automatic-semantic-versioning-in-gitlab-ci/
import os
import re
import sys
import semver
import subprocess

def git(*args):
    return subprocess.check_output(["git"] + list(args))


def tag_repo(tag):
    url = os.environ["CI_REPOSITORY_URL"]

    # Transforms the repository URL to the SSH URL
    # Example input: https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@gitlab.com/threedotslabs/ci-examples.git
    # Example output: git@gitlab.com:threedotslabs/ci-examples.git
    push_url = re.sub(r'.+@([^/]+)/', r'git@\1:', url)

    git("remote", "set-url", "--push", "origin", push_url)
    git("tag", tag)
    git("push", "origin", tag)


def bump(latest):
    # refer to: https://stackoverflow.com/questions/22021825/how-to-do-a-git-diff-of-current-commit-with-last-commit-using-gitpython
    content = repo.index.diff(repo.commit('HEAD~1'), create_patch=True)

    if "app.py" in content:
        return semver.bump_major(latest)
        #on logical changes in application increase version-majornumber example: increase 1.0.0 to 2.0.0
    elif "templates/" in content:
        return semver.bump_minor(latest)
        #on html-template changes increase version-minornumber example: increase 1.0.0 to 1.1.0
    elif "static/scripts" in content:
        return semver.bump_minor(latest)
        #on script changes increase version-minornumber example: increase 1.0.0 to 1.1.0
    elif "static/styles/" in content:
        return semver.bump_patch(latest)
        #on css changes increase version-patchnumber example: increase 1.0.0 to 1.0.1
    elif "static/img/" in content:
        return semver.bump_patch(latest)
        #on img changes increase version-patchnumber example: increase 1.0.0 to 1.0.1
    elif ".git" in content:
        return latest
        #Do not increase version on git conf changes
    elif "deb-pkg-data/" in content:
        return latest
        #Do not increase version on packaging script changes
    else:
        return semver.bump_patch(latest)
        #Default: increase version-patchnumber example: increase 1.0.0 to 1.0.1


def main():
    try:
        latest = git("describe", "--tags").decode().strip()
    except subprocess.CalledProcessError:
        # No tags in the repository
        version = "1.0.0"
    else:
        # Skip already tagged commits
        if '-' not in latest:
            print(latest)
            return 0

        version = bump(latest)
        if version == latest:
            return 0

    tag_repo(version)
    print(version)

    return 0


if __name__ == "__main__":
    sys.exit(main())

The script generally works. The only thing that does not is my part with the if and elif. Generally I want to get a git diff --name-only to pass to my conditionals. If there is a change in app.py I always want to bump my major version.

EDIT: I have tried the following and I am getting the following error: subprocess.CalledProcessError: Command '['git', 'diff', '--name-only', '>', 'patchedfiles.txt']' returned non-zero exit status 128. My improved code:

git("diff", "--name-only", ">", "patchedfiles.txt")
    patchedFiles = open("patchedfiles.txt", "r")
    content = patchedFiles.read()
    if "app.py" in content:
        patchedFiles.close()
        os.remove("patchedfiles.txt")
        return semver.bump_major(latest)
        #on logical changes in application increase version-majornumber example: increase 1.0.0 to 2.0.0

Solution

I did solve it with the help of a colleague. We made a different approach - we tried to analyze the commit message in git for certain keywords. If anyone wants to know the answer to my problem - here it is:

#!/usr/bin/env python3
import os
import re
import sys
import semver
import subprocess

def git(*args):
    return subprocess.check_output(["git"] + list(args))


def tag_repo(tag):
    url = os.environ["CI_REPOSITORY_URL"]

    # Transforms the repository URL to the SSH URL
    # Example input: https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@gitlab.com/threedotslabs/ci-examples.git
    # Example output: git@gitlab.com:threedotslabs/ci-examples.git
    push_url = re.sub(r'.+@([^/]+)/', r'git@\1:', url)

    git("remote", "set-url", "--push", "origin", push_url)
    git("tag", tag)
    git("push", "origin", tag)


def bump(latest):
    MyOutput = subprocess.Popen(['git', 'log', '--format=%B', '-n', '1', 'HEAD'], 
            stdout=subprocess.PIPE, 
            stderr=subprocess.STDOUT)
    stdout,stderr = MyOutput.communicate()
    if stderr != None:
        return latest
    else: 
        commitMSG = stdout.decode("utf8")
        try:
            words = commitMSG.lower()
            if "major" in words:
                return semver.bump_major(latest)
            elif "minor" in words:
                return semver.bump_minor(latest)
            elif "patch" in words:
                return semver.bump_patch(latest)
            else:
                return latest # return latest already existing version if no keyword is used in the commit message
        except:
            print("encountered non-char object in commit msg - moving on")

def main():
    try:
        latest = git("describe", "--tags").decode().strip()
    except subprocess.CalledProcessError:
        # No tags in the repository
        version = "1.0.0"
    else:
        # Skip already tagged commits
        if '-' not in latest:
            print(latest)
            return 0

        version = bump(latest)
        if version == latest:
            return 0

    tag_repo(version)
    print(version)

    return 0


if __name__ == "__main__":
    sys.exit(main())



Answered By - LegendaryCodingNoob
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing