Compare commits

...

35 Commits

Author SHA1 Message Date
cclecle
d5e003c86c update Jenkinsfile 2023-03-19 22:40:38 +00:00
cclecle
8b2b0ca07f update jenkinsfile 2023-03-19 22:31:15 +00:00
cclecle
ab1a69b8f8 cleaning jenkins file
updating documentation in toml
2023-03-19 22:08:22 +00:00
cclecle
a564e04219 fix: remove setuptools-git-versioning stuff 2023-03-19 22:03:09 +00:00
cclecle
a29c1778fc test: fall back to setuptools_scm 2023-03-19 21:57:15 +00:00
cclecle
2ee687959e fix: typo 2023-03-19 21:01:45 +00:00
cclecle
e226f16292 fix: typo 2023-03-19 20:54:02 +00:00
cclecle
8ea6b43a73 fix: git remote credentials 2023-03-19 20:50:50 +00:00
cclecle
cb213df6b6 fix: workaround for setuptools-git-versioning version guess 2023-03-19 20:44:31 +00:00
cclecle
2c87f5488d test: bump dev version 2023-03-19 20:05:32 +00:00
cclecle
348204abb5 fix: project username 2023-03-19 19:59:01 +00:00
cclecle
48114149fb fix: typo in jenkins pipeline file 2023-03-19 19:54:46 +00:00
cclecle
5eb2f1c5cf fix: pipeline 2023-03-19 19:50:23 +00:00
cclecle
65927077aa fix: git credentials for pushing 2023-03-19 19:49:57 +00:00
cclecle
0c02512814 fix: remove branch on git push (useless) 2023-03-19 19:35:37 +00:00
cclecle
9f900ba597 fix git tag cmd 2023-03-19 19:31:37 +00:00
cclecle
97612703b7 fix git username/address in jenkinsfile 2023-03-19 19:26:04 +00:00
cclecle
5bb8b35c73 update jenkinsfile 2023-03-19 19:21:48 +00:00
cclecle
a6c2513d9f fix fstrings 2023-03-19 18:55:58 +00:00
cclecle
70ef90a529 fix jenkinsfile python 2023-03-19 18:53:52 +00:00
cclecle
f728842a5a random fixes 2023-03-19 18:51:35 +00:00
cclecle
4837a99ac6 fix deps 2023-03-19 18:46:52 +00:00
cclecle
3e130e6bdf revert to full setuptools-git-versioning in toml file 2023-03-19 18:42:24 +00:00
cclecle
d7fbf52647 test 2023-03-19 18:23:42 +00:00
cclecle
f5c97757b6 make setuptools-git-versioning use pygitversionhelper
+ add getCurrentFormatedVersion()
2023-03-19 18:22:26 +00:00
cclecle
3c0e5bebc2 update doc 2023-03-19 18:02:02 +00:00
cclecle
c5962d533b fix tag -> version api 2023-03-19 17:59:27 +00:00
cclecle
e9e25793d8 fix doc bullets 2023-03-19 17:57:28 +00:00
cclecle
17f74d6675 test gitversionhelper calls 2023-03-19 17:57:20 +00:00
cclecle
264c51de2e update CI/CD 2023-03-19 17:51:11 +00:00
cclecle
ac942480cb feature: add log-line in pipeline 2023-03-19 10:34:34 +00:00
cclecle
be9ef684e4 update jenkinsFile => no error when master build are skipped because of
no-tag
2023-03-19 10:26:23 +00:00
cclecle
792666c6ec fix: rename hash -> commit_hash to avoid using builtin symbol 2023-03-19 10:17:58 +00:00
cclecle
2951e70c47 fix: escapes git strings options 2023-03-19 10:15:23 +00:00
cclecle
63b3f25b33 fix quality warning + commit messages unittest 2023-03-19 10:03:50 +00:00
5 changed files with 161 additions and 89 deletions

141
Jenkinsfile vendored
View File

@@ -6,6 +6,8 @@
// You should have received a copy of the license along with this
// work. If not, see <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
// configurable settings:
// use to send email if workflow problem
def _MaintainerName = "CHACHA"
@@ -17,7 +19,7 @@ def _bPreRelease = false
// toogle Draft flag on Gitea release system => If False, TAG is not created
def _bDraft = false
// release content / changelog management
def _bAutoChangelog = false //Not supported yet
def _bAutoChangelog = true //Not supported yet
def _ReleaseContent_Title = "_CI/CD Automatic Release_"
// full rebuild toogle
def _bFullRebuilt = true
@@ -99,7 +101,7 @@ pipeline {
stage("Prepare") {
steps {
script{
script {
if (_bFullRebuilt) {
// start by cleaning the workspace (not using cleanWs() because we want to keep the directory itself)
// => this is needed to fetch it again with custom options
@@ -108,8 +110,7 @@ pipeline {
else {
sh("find ~/. -name . ! -path './TEST_ENV/*' ! -path './BUILD_ENV/*' -o -prune -exec rm -rf -- {} +")
}
if(_GIT_BRANCH!="master")
{
if(_GIT_BRANCH!="master") {
_bPreRelease = true
}
}
@@ -120,51 +121,92 @@ pipeline {
echo("_GITEA_BASE_URL: . . . . . . . . $_GITEA_BASE_URL")
echo("GIT_COMMIT:. . . . . . . . . . . $GIT_COMMIT ")
echo("_PROJECT_USER_NAME:. . . . . . . $_PROJECT_USER_NAME")
echo("_GITEA_PROJECT_NAME: . . . . . . $_PROJECT_NAME")
echo("_PROJECT_NAME: . . . . . . . . . $_PROJECT_NAME")
echo("_MaintainerEmail:. . . . . . . . $_MaintainerEmail")
echo("_MaintainerName:. . . . . . . . $_MaintainerName")
sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python BUILD_ENV")
sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TEST_ENV")
sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TOOLS_ENV")
sh(". ~/BUILD_ENV/bin/activate && pip install --upgrade setuptools build pip copier jinja2-slug toml \"setuptools-git-versioning<2\"")
sh(". ~/TOOLS_ENV/bin/activate && pip install simple_rest_client requests")
sh(". ~/TOOLS_ENV/bin/activate && pip install git+https://chacha.ddns.net/gitea/chacha/pygitversionhelper.git@master")
sh("git config --global user.email $_MaintainerEmail")
sh("git config --global user.name $_MaintainerName")
}
}
stage("GetCode") {
steps {
dir("gitrepo") {
// manually checkout the repository, with All branches and tags
// manually checkout the repository, with All branches and tags
// => because we might need them for version and changelog computing
checkout([ $class: "GitSCM",
branches: [[name: GIT_BRANCH]],
extensions: [[$class: "CloneOption", noTags: false, shallow: false, depth: 0, reference: '']],
userRemoteConfigs: [[credentialsId: _SCMCredentials, url: GIT_URL]]])
script{
if(_GIT_BRANCH=="master")
{
if(sh(returnStdout: true, script: "git tag --points-at HEAD").trim().isEmpty())
{
error("master push/merge must have an explicit tag release number")
script {
withCredentials([usernamePassword(credentialsId: _SCMCredentials, passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
sh("git remote set-url origin https://${GIT_USERNAME}:${GIT_PASSWORD}@chacha.ddns.net/gitea/${_PROJECT_USER_NAME}/${_PROJECT_NAME}.git")
}
if(_GIT_BRANCH=="master") {
if(sh(returnStdout: true, script: "git tag --points-at HEAD").trim().isEmpty()) {
BUMPED_VERSION = sh(script: """#!/bin/sh -
|. ~/TOOLS_ENV/bin/activate
|exec python - << '__EOWRAPPER__'
|
|from pygitversionhelper import gitversionhelper
|import re
|
|lastcommit=gitversionhelper.commit.getLast(same_branch=True)
|msg=gitversionhelper.commit.getMessage(lastcommit)
|
|_match=re.search(r"\\s*(?:#)?\\s*(?<=new-tag:)(?:\\s*)(?P<TAG>\\S*)",msg)
|print(_match.group("TAG"),end="")
|
|__EOWRAPPER__
""".stripMargin(),
returnStdout: true).trim()
if(BUMPED_VERSION.isEmpty()) {
echo "master push/merge must have an explicit tag release number, stopping pipeline"
currentBuild.getRawBuild().getExecutor().doStop()
}
else {
echo "new-tag requested in commit message: $BUMPED_VERSION"
sh("git tag $BUMPED_VERSION")
sh("git push origin --tags")
}
}
}
// using git to get the latest tag on this branch
def latestTag = sh(returnStdout: true, script: "git tag --sort=-creatordate | head -n 1").trim()
latestTag = sh(script: """#!/bin/sh -
|. ~/TOOLS_ENV/bin/activate
|exec python - << '__EOWRAPPER__'
|
|from pygitversionhelper import gitversionhelper
|
|print(gitversionhelper.tag.getLastTag(same_branch=True),end ="")
|
|__EOWRAPPER__
""".stripMargin(),
returnStdout: true)
echo("latestTag:. . . . . . . . . . . . $latestTag ")
// using setuptools_git_versioning to get the generated version number based on Git tags and logs
// TODO: read dev_template from toml
// get current (or bumped) version number from git history
PY_PROJECT_VERSION = sh(script: """#!/bin/sh -
|. ~/BUILD_ENV/bin/activate
|. ~/TOOLS_ENV/bin/activate
|exec python - << '__EOWRAPPER__'
|
|from setuptools_git_versioning import version_from_git
|from pygitversionhelper import gitversionhelper
|
|print(str(version_from_git(tag_filter="^\\d+\\.\\d+\\.\\d+\$",dev_template = "{tag}.post{ccount}")),end ="")
|print(gitversionhelper.version.getCurrentVersion(formated_output=True,version_std="PEP440",bump_type="dev",bump_dev_strategy="post"),end ="")
|
|__EOWRAPPER__
""".stripMargin(),
@@ -172,13 +214,16 @@ pipeline {
echo("PY_PROJECT_VERSION: . . . . . . . . . $PY_PROJECT_VERSION")
PY_PROJECT_VERSION_STRIPPED=ExtractBaseVersion(PY_PROJECT_VERSION)
// Manually pushing a new tag with version string guessed by gitversionhelper
// because setuptools-git-versioning cant fing tag on other branches, so will guess a wring version without this tag.
if(latestTag!=PY_PROJECT_VERSION) {
sh("git tag $PY_PROJECT_VERSION")
sh("git push origin --tags")
}
// specific handling to test the template itself
// => little hacky... creating a new git repo with a commit/tag corresponding to HEAD of the official one
if(_PROJECT_NAME=="pyChaChaDummyProject") //specific case to test the template itself
{
sh("git config --global user.email $_MaintainerEmail")
sh("git config --global user.name $_MaintainerName")
if(_PROJECT_NAME=="pyChaChaDummyProject") { //specific case to test the template itself
sh("rm -Rf ~/_gitrepo || true")
sh(script: """#!/bin/sh -
@@ -239,7 +284,7 @@ pipeline {
steps {
// no need for a build-env: setuptools is already creating one
dir("gitrepo") {
script{
script {
// actually doing the package build
sh(". ~/BUILD_ENV/bin/activate && python -m build .")
}
@@ -268,16 +313,16 @@ pipeline {
}
}
post {
always {
dir("gitrepo") {
publishHTML([
reportDir: "helpers-results/quality_check",
reportFiles: "report.html",
reportName: "quality-report",
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true])
}
always {
dir("gitrepo") {
publishHTML([
reportDir: "helpers-results/quality_check",
reportFiles: "report.html",
reportName: "quality-report",
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true])
}
}
}
}
@@ -387,20 +432,23 @@ pipeline {
def GITEA_LOGIN_TOKEN=credentials("GiteaCHACHAPush")
}
steps {
sh("python3 -m pip install simple_rest_client requests")
dir("gitrepo") {
script {
def CurrentDateTime=java.time.LocalDateTime.now()
withCredentials([string( credentialsId: _MkDocsWebCredentials,variable: 'MKDOCSTOKEN' )])
{
sh(script: """#!/usr/bin/env python3
|from simple_rest_client.api import API
|from simple_rest_client.resource import Resource
withCredentials([string( credentialsId: _MkDocsWebCredentials,variable: 'MKDOCSTOKEN' )]) {
sh(script: """#!/bin/sh -
|. ~/TOOLS_ENV/bin/activate
|exec python - << '__EOWRAPPER__'
|
|import json
|import glob
|import requests
|import shutil
|
|from simple_rest_client.api import API
|from simple_rest_client.resource import Resource
|from pygitversionhelper import gitversionhelper
|
|from urllib.parse import urljoin
|
|class GiteaRepoCommits(Resource):
@@ -477,8 +525,9 @@ pipeline {
|response=requests.post("http://${_MkDocsWebURL}/API.php?REQ=pushDoc",data=reqData,files=files)
|if response.status_code != 200:
| raise RuntimeError(f"Wrong server response: {response.status_code}")
|
""".stripMargin())
|
|__EOWRAPPER__
""".stripMargin())
}
}
}

View File

@@ -75,25 +75,39 @@ Get the distance from HEAD to last tag [only on same branch]:
Get the last found version in the repository [return MetaVersion object]:
print(f"most recent repository version: {gitversionhelper.tag.getLastVersion()}")
print(f"most recent repository version: {gitversionhelper.version.getLastVersion()}")
Get the last found version in the repository [return formated string]:
print(f"most recent repository version: {gitversionhelper.tag.getLastVersion(formated_output=True)}")
print(f"most recent repository version: {gitversionhelper.version.getLastVersion(formated_output=True)}")
Others kwargs available to this function:
- version_std: string to force a version standard for rendering ["PEP440" or "SemVer"]
- same_branch: boolean to force searching on same branch
- ignore_unknown_tags: boolean to allow unknown tag to be ignored
* version_std: string to force a version standard for rendering ["PEP440" or "SemVer"]
* same_branch: boolean to force searching on same branch
* ignore\_unknown\_tags: boolean to allow unknown tag to be ignored
Get the current version of the repository, automatically bump it if the last one is not tagged [returns MetaVersion object]:
print(f"most recent repository version: {gitversionhelper.tag.getCurrentVersion()}")
print(f"current repository version: {gitversionhelper.version.getCurrentVersion()}")
Or with formated output:
print(f"current repository version: {gitversionhelper.version.getCurrentVersion(formated_output=True)}")
Typical usage in CI/CD env:
bumped_version = gitversionhelper.version.getCurrentVersion( formated_output=True, \
version_std="PEP440", \
bump_type="dev", \
bump_dev_strategy="post")
print(f"current repository version: {bumped_version}")
kwargs available to this function:
- All same args as getLastVersion()
- bump_type: if version need to be pump, allow to configure next release update type: major, minor, patch, dev
- bump_dev_strategy: if bump_type is dev, allow to choose dev update strategy: post, pre-patch, pre-minor, pre-major
* All same args as getLastVersion()
* bump_type: if version need to be pump, allow to configure next release update type: __major, minor, patch, dev__
* bump\_dev\_strategy: if bump\_type is dev, allow to choose dev update strategy: __post, pre-patch, pre-minor, pre-major__
A version object can also be manually formated:
@@ -108,6 +122,7 @@ kwargs available to those function:
## Limitations
There is unfortunately some technical limitation :
- MultiThreading and async behavior is not tested.
- Multiple tag on the same commit is not supported.
- Branch filter when searching for a version is only tested with -no-ff strategy
* MultiThreading and async behavior is not tested.
* Multiple tag on the same commit is not supported.
* Branch filter when searching for a version is only tested with -no-ff strategy

View File

@@ -7,13 +7,11 @@
# work. If not, see <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
[build-system]
requires = ["setuptools>=63", "wheel", "setuptools-git-versioning<2"]
requires = ["setuptools>=63", "wheel", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools-git-versioning]
enabled = true
dev_template = "{tag}.post{ccount}"
tag_filter = "^\\d+\\.\\d+\\.\\d+$"
[tool.setuptools_scm]
version_scheme= "post-release"
[project]
name = "pygitversionhelper"
@@ -36,6 +34,7 @@ classifiers = [
]
dependencies = [
'importlib-metadata; python_version<"3.9"',
'packaging'
]
dynamic = ["version"]
@@ -49,13 +48,9 @@ where = ["src"]
[tool.setuptools.package-data]
"pygitversionhelper.data" = ["*.*"]
#[tool.setuptools_scm]
#write_to = "src/pygitversionhelper/_version.py"
#version_scheme = "python-simplified-semver"
[project.urls]
Homepage = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper"
Documentation = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/wiki"
Homepage = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/"
Documentation = "https://chacha.ddns.net/mkdocs-web/chacha/pygitversionhelper/master/latest/"
Tracker = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/issues"
[project.optional-dependencies]

View File

@@ -53,7 +53,7 @@ def _exec(cmd: str, root: str | os.PathLike | None = None, raw:bool = False) ->
raise gitversionhelper.unknownGITFatalError(p.stderr)
if int(p.returncode) < 0: #pragma: nocover
raise gitversionhelper.unknownGITError(p.stderr)
if raw:
return p.stdout
lines = p.stdout.splitlines()
@@ -126,7 +126,7 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
"""
tag not found exception
"""
@classmethod
def getMessagesSinceTag(cls,tag:str,**kwargs) -> str:
"""
@@ -139,39 +139,39 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
the commit message
"""
current_commit_id=cls.getLast(**kwargs)
tag_commit_id=cls.getFromTag(tag,**kwargs)
if ((cls.__OptDict["same_branch"] in kwargs) and (kwargs[cls.__OptDict["same_branch"]] is True)):
tag_commit_id=cls.getFromTag(tag)
if ((cls.__OptDict["same_branch"] in kwargs) and (kwargs[cls.__OptDict["same_branch"]] is True)):
commits = _exec(f"git rev-list --first-parent --ancestry-path {tag_commit_id}..{current_commit_id}")
else:
commits = _exec(f"git rev-list --ancestry-path {tag_commit_id}..{current_commit_id}")
result=[]
for commit in commits:
result.append(cls.getMessage(commit,**kwargs))
if ((cls.__OptDict["merged_output"] in kwargs) and (kwargs[cls.__OptDict["merged_output"]] is True)):
result.append(cls.getMessage(commit))
if ((cls.__OptDict["merged_output"] in kwargs) and (kwargs[cls.__OptDict["merged_output"]] is True)):
print("JOIN")
return os.linesep.join(result)
return result
@classmethod
def getMessage(cls, id:str, **kwargs) -> str:
def getMessage(cls, commit_hash:str) -> str:
"""
retrieve a commit message from repository
Args:
id: id of the commit
commit_hash: id of the commit
Returns:
the commit message
"""
try:
res=_exec(f"git log -z --pretty=tformat:%B%-C() -n 1 {id}",None,True).rstrip('\x00')
res=_exec(f"git log -z --pretty=\"tformat:%B%-C()\" -n 1 {commit_hash}",None,True).rstrip('\x00')
except gitversionhelper.unknownGITFatalError as _e:
raise cls.commitNotFound("no commit found in commit history") from _e
return res.replace('\r\n','\n').replace('\n','\r\n')
@classmethod
def getFromTag(cls,tag:str,**kwargs) -> str:
def getFromTag(cls,tag:str) -> str:
"""
retrieve a commit from repository associated to a tag
Args:
@@ -196,14 +196,14 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
Returns:
the commit Id
"""
if ((cls.__OptDict["same_branch"] in kwargs) and (kwargs[cls.__OptDict["same_branch"]] is True)):
if ((cls.__OptDict["same_branch"] in kwargs) and (kwargs[cls.__OptDict["same_branch"]] is True)):
try:
res = _exec("git rev-parse HEAD")
except gitversionhelper.unknownGITFatalError as _e:
raise cls.commitNotFound("no commit found in commit history") from _e
else:
res = _exec("git for-each-ref --sort=-committerdate refs/heads/ --count 1 --format=%(objectname)")
res = _exec("git for-each-ref --sort=-committerdate refs/heads/ --count 1 --format=\"%(objectname)\"")
if len(res)==0:
raise cls.commitNotFound("no commit found in commit history")
return res[0]
@@ -494,6 +494,14 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
return _v.doFormatVersion(**kwargs)
return _v
@classmethod
def getCurrentFormatedVersion(cls,**kwargs) -> str :
"""
Same as getCurrentVersion() with formated_output kwarg activated
"""
kwargs["formated_output"]=True
return cls.getCurrentVersion(kwargs)
@classmethod
def _parseTag(cls,tag,**kwargs): # pylint: disable=R0914, R0912, R0915
"""get the last version from tags

View File

@@ -1235,7 +1235,7 @@ class Test_gitversionhelper(unittest.TestCase):
pygitversionhelper.gitversionhelper.commit.getFromTag("TAG")
def test_nominal__commit_getMessage(self):
commit_message="AAAABBB CCCCDDDD"
commit_message="AAAABBB CCCCDDDD".replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue")
os.system("git add .")
@@ -1247,7 +1247,8 @@ class Test_gitversionhelper(unittest.TestCase):
def test_nominal__commit_getMessage2(self):
commit_message="""AAAABBB
CCCCDDDD
-f dfsds dfsdfs $"""
-f dfsds dfsdfs $""".replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue")
os.system("git add .")
@@ -1258,13 +1259,14 @@ class Test_gitversionhelper(unittest.TestCase):
commit = pygitversionhelper.gitversionhelper.commit.getLast()
message = pygitversionhelper.gitversionhelper.commit.getMessage(commit)
print(message)
self.assertEqual(message,commit_message)
def test_nominal__commit_getMessagesSinceLastTag(self):
commit_message1="1.1 update this"+ os.linesep+\
"1.1 fix that" + os.linesep+\
"1.1 test"
commit_message1=commit_message1.replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue")
os.system("git add .")
@@ -1277,6 +1279,7 @@ class Test_gitversionhelper(unittest.TestCase):
commit_message2="2.1 update this"+ os.linesep+\
"2.1 fix that" + os.linesep+\
"2.1 test"
commit_message2=commit_message2.replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue2")
os.system("git add .")
@@ -1288,6 +1291,7 @@ class Test_gitversionhelper(unittest.TestCase):
commit_message3="3.1 update this"+ os.linesep+\
"3.1 fix that" + os.linesep+\
"3.1 test"
commit_message3=commit_message3.replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue3")
os.system("git add .")
@@ -1299,6 +1303,7 @@ class Test_gitversionhelper(unittest.TestCase):
commit_message4="4.1 update this" + os.linesep+\
"4.1 fix that" + os.linesep+\
"4.1 test"
commit_message4=commit_message4.replace('\r\n','\n').replace('\n','\r\n')
with open("demofile.txt", "w+t") as tmpFile:
tmpFile.write("testvalue4")
os.system("git add .")