Skip to content

Commit ae3e2e0

Browse files
authored
Added a golang plugin (#21)
1 parent c219fe3 commit ae3e2e0

File tree

12 files changed

+171
-23
lines changed

12 files changed

+171
-23
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Golang plugin
2+
3+
This plugin is used for golang projects when `PROGRAMMING_LANGUAGE` is set to `golang`.
4+
5+
In order to work, `go > 1.16` is required.
6+
7+
## Release
8+
The plugin leverages [goreleaser](https://goreleaser.com/) to package and release projects.
9+
Therefore, a `.goreleaser.yml` file must be present in the go source directory i.e. where the mod file lies.
10+
11+
## Documentation
12+
The plugin uses [golds](https://github.com/go101/golds) to generate the code reference documentation.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# No Op plugin
2+
3+
This plugin is used for simple git projects when `PROGRAMMING_LANGUAGE` is set to `noop`.
4+
5+
## Release
6+
Only git operations (tagging, version incrementation, changelog commit) are performed
7+
8+
## Documentation
9+
N/A
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Python plugin
2+
3+
This plugin is used for python projects when `PROGRAMMING_LANGUAGE` is set to `python`.
4+
5+
## Release
6+
The plugin uses `wheel` to package the project before releasing it.
7+
8+
The plugin uses twine to release packages to PYPI.
9+
For that purpose, two environment variables need to be set:
10+
- `TWINE_USERNAME`: the username of the PYPI account
11+
- `TWINE_PASSWORD`: the password of the PYPI account
12+
13+
## Documentation
14+
The plugin uses [pdoc](https://pdoc3.github.io/pdoc/) to generate the code reference documentation

continuous_delivery_scripts/plugins/docker.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ def get_related_language(self) -> str:
1919
"""Gets the related language."""
2020
return get_language_from_file_name(__file__)
2121

22-
def package_software(self) -> None:
22+
def package_software(self, version: str) -> None:
2323
"""Todo build docker image."""
24-
super().package_software()
24+
super().package_software(version)
2525

26-
def release_package_to_repository(self) -> None:
26+
def release_package_to_repository(self, version: str) -> None:
2727
"""Todo push image to repository e.g. ecr, artifactory."""
28-
super().release_package_to_repository()
28+
super().release_package_to_repository(version)
2929

3030
def check_credentials(self) -> None:
3131
"""Checks any credentials."""

continuous_delivery_scripts/plugins/golang.py

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,80 @@
44
#
55
"""Plugin for Golang projects."""
66
import logging
7+
import os
78
from pathlib import Path
8-
from typing import Optional
9+
from typing import Optional, List
10+
from subprocess import check_call
911
from continuous_delivery_scripts.utils.language_specifics_base import BaseLanguage, get_language_from_file_name
1012
from continuous_delivery_scripts.spdx_report.spdx_project import SpdxProject
13+
from continuous_delivery_scripts.utils.configuration import configuration, ConfigurationVariable
1114

1215
logger = logging.getLogger(__name__)
1316

17+
SRC_DIR = configuration.get_value(ConfigurationVariable.SOURCE_DIR)
18+
ENVVAR_GORELEASER_GIT_TOKEN = "GITHUB_TOKEN"
19+
ENVVAR_GORELEASER_CUSTOMISED_TAG = "GORELEASER_CURRENT_TAG"
20+
21+
22+
def _generate_golds_command_list(output_directory: Path, module: str) -> List[str]:
23+
return ["golds", "-gen", "-wdpkgs-listing=promoted", f"-dir={str(output_directory)}", "-nouses", f"{module}"]
24+
25+
26+
def _generate_goreleaser_release_command_list(changelog: Path) -> List[str]:
27+
return [
28+
"goreleaser",
29+
"release",
30+
"--rm-dist",
31+
"--release-notes",
32+
f"{str(changelog)}",
33+
]
34+
35+
36+
def _generate_goreleaser_check_command_list() -> List[str]:
37+
return [
38+
"goreleaser",
39+
"check",
40+
]
41+
42+
43+
def _install_golds_command_list() -> List[str]:
44+
return ["go", "install", "go101.org/golds@latest"]
45+
46+
47+
def _install_goreleaser_command_list() -> List[str]:
48+
return ["go", "install", "github.com/goreleaser/goreleaser@latest"]
49+
50+
51+
def _call_golds(output_directory: Path, module: str) -> None:
52+
"""Calls Golds for generating the docs."""
53+
logger.info("Installing Golds if missing.")
54+
check_call(_install_golds_command_list())
55+
logger.info("Creating Golds documentation.")
56+
check_call(_generate_golds_command_list(output_directory, module), cwd=SRC_DIR)
57+
58+
59+
def _call_goreleaser_check(version: str) -> None:
60+
"""Calls go releaser check to verify configuration."""
61+
logger.info("Installing GoReleaser if missing.")
62+
check_call(_install_goreleaser_command_list())
63+
logger.info("Checking GoReleaser configuration.")
64+
env = os.environ
65+
env[ENVVAR_GORELEASER_CUSTOMISED_TAG] = version
66+
env[ENVVAR_GORELEASER_GIT_TOKEN] = configuration.get_value(ConfigurationVariable.GIT_TOKEN)
67+
check_call(_generate_goreleaser_check_command_list(), cwd=SRC_DIR)
68+
69+
70+
def _call_goreleaser_release(version: str) -> None:
71+
"""Calls go releaser release to upload packages."""
72+
logger.info("Installing GoReleaser if missing.")
73+
check_call(_install_goreleaser_command_list())
74+
logger.info("Release package.")
75+
changelogPath = configuration.get_value(ConfigurationVariable.CHANGELOG_FILE_PATH)
76+
env = os.environ
77+
env[ENVVAR_GORELEASER_CUSTOMISED_TAG] = version
78+
env[ENVVAR_GORELEASER_GIT_TOKEN] = configuration.get_value(ConfigurationVariable.GIT_TOKEN)
79+
check_call(_generate_goreleaser_release_command_list(changelogPath), cwd=SRC_DIR, env=env)
80+
1481

1582
class Go(BaseLanguage):
1683
"""Specific actions for a Golang project."""
@@ -19,22 +86,30 @@ def get_related_language(self) -> str:
1986
"""Gets the related language."""
2087
return get_language_from_file_name(__file__)
2188

22-
def package_software(self) -> None:
89+
def get_version_tag(self, version: str):
90+
"""Gets tag based on version."""
91+
cleansed_version = version.strip().lstrip("v")
92+
return f"v{cleansed_version}"
93+
94+
def package_software(self, version: str) -> None:
2395
"""No operation."""
24-
super().package_software()
96+
super().package_software(version)
97+
_call_goreleaser_check(version)
2598

26-
def release_package_to_repository(self) -> None:
99+
def release_package_to_repository(self, version: str) -> None:
27100
"""No operation."""
28-
super().release_package_to_repository()
101+
super().release_package_to_repository(version)
102+
_call_goreleaser_release(version)
29103

30104
def check_credentials(self) -> None:
31105
"""Checks any credentials."""
32106
super().check_credentials()
107+
configuration.get_value(ConfigurationVariable.GIT_TOKEN)
33108

34109
def generate_code_documentation(self, output_directory: Path, module_to_document: str) -> None:
35110
"""Generates the code documentation."""
36111
super().generate_code_documentation(output_directory, module_to_document)
37-
# TODO
112+
_call_golds(output_directory, "./...")
38113

39114
def can_add_licence_headers(self) -> bool:
40115
"""States that licence headers can be added."""

continuous_delivery_scripts/plugins/noop.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ def get_related_language(self) -> str:
2020
"""Gets the related language."""
2121
return get_language_from_file_name(__file__)
2222

23-
def package_software(self) -> None:
23+
def package_software(self, version: str) -> None:
2424
"""No Op."""
25-
super().package_software()
25+
super().package_software(version)
2626

27-
def release_package_to_repository(self) -> None:
27+
def release_package_to_repository(self, version: str) -> None:
2828
"""No Op."""
29-
super().release_package_to_repository()
29+
super().release_package_to_repository(version)
3030

3131
def check_credentials(self) -> None:
3232
"""No Op."""

continuous_delivery_scripts/plugins/python.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ def get_related_language(self) -> str:
134134
"""Gets related language."""
135135
return get_language_from_file_name(__file__)
136136

137-
def package_software(self) -> None:
137+
def package_software(self, version: str) -> None:
138138
"""Packages the software into a wheel."""
139-
super().package_software()
139+
super().package_software(version)
140140
_create_wheel()
141141

142-
def release_package_to_repository(self) -> None:
142+
def release_package_to_repository(self, version: str) -> None:
143143
"""Releases to PyPI."""
144-
super().release_package_to_repository()
144+
super().release_package_to_repository(version)
145145
_release_to_pypi()
146146

147147
def check_credentials(self) -> None:

continuous_delivery_scripts/tag_and_release.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def _update_repository(mode: CommitType, is_new_version: bool, version: str, cur
9191
_commit_release_changes(git, version, commit_message)
9292
if is_new_version:
9393
logger.info("Tagging commit")
94-
git.create_tag(version, message=f"release {version}")
94+
git.create_tag(get_language_specifics().get_version_tag(version), message=f"release {version}")
9595
git.force_push_tag()
9696

9797

continuous_delivery_scripts/utils/configuration.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,70 @@ class ConfigurationVariable(enum.Enum):
2222
"""Project's configuration variables."""
2323

2424
PROJECT_ROOT = 1
25+
"""Relative path to the root of the project from pyproject.toml."""
2526
PROJECT_CONFIG = 2
27+
"""Relative path to the file comprising project's configuration."""
2628
NEWS_DIR = 3
29+
"""Relative path to the directory comprising news files."""
2730
VERSION_FILE_PATH = 4
31+
"""Relative path to the file comprising project's version."""
2832
CHANGELOG_FILE_PATH = 5
33+
"""Relative path to the changelog file."""
2934
MODULE_TO_DOCUMENT = 6
35+
"""Name of the module to generate documentation for."""
3036
DOCUMENTATION_DEFAULT_OUTPUT_PATH = 7
3137
DOCUMENTATION_PRODUCTION_OUTPUT_PATH = 8
38+
"""Relative path to the folder where documentation will be generated."""
3239
GIT_TOKEN = 9
40+
"""GIT token allowing committing back to the repository."""
3341
BETA_BRANCH = 10
42+
"""Name of beta/QA branch."""
3443
MASTER_BRANCH = 11
44+
"""Name of the main/production branch."""
3545
RELEASE_BRANCH_PATTERN = 12
46+
"""Pattern of release branches."""
3647
REMOTE_ALIAS = 13
48+
"""Git's remote alias."""
3749
LOGGER_FORMAT = 14
50+
"""Tools' logger format."""
3851
BOT_USERNAME = 15
52+
"""Username of the Git bot account."""
3953
BOT_EMAIL = 16
54+
"""Email of the Git bot account."""
4055
ORGANISATION = 17
56+
"""Name of the organisation managing the project."""
4157
ORGANISATION_EMAIL = 18
58+
"""Email of the organisation managing the project."""
4259
AWS_BUCKET = 19
60+
"""AWS bucket to use if needed."""
4361
PROJECT_NAME = 21
62+
"""Name of the project."""
4463
PROJECT_UUID = 22
64+
"""UUID of the project to use in SPDX reports."""
4565
PACKAGE_NAME = 23
66+
"""Name of the package."""
4667
SOURCE_DIR = 24
68+
"""Relative path to the source of the project."""
4769
IGNORE_REPOSITORY_TEST_UPLOAD = 25
70+
"""States whether to release package to a test registry (e.g. pypi test) test before release."""
4871
FILE_LICENCE_IDENTIFIER = 26
72+
"""SPDX identifier for the project's licence."""
4973
COPYRIGHT_START_DATE = 27
74+
"""Project's copyright start year."""
5075
ACCEPTED_THIRD_PARTY_LICENCES = 28
76+
"""List of accepted 3rd party licences for dependencies."""
5177
PACKAGES_WITH_CHECKED_LICENCE = 29
78+
"""List of dependencies whose licence was manually checked."""
5279
PROGRAMMING_LANGUAGE = 30
80+
"""Project's programming language."""
5381
AUTOGENERATE_NEWS_FILE_ON_DEPENDENCY_UPDATE = 31
82+
"""States whether news file should be generated on dependency updates."""
5483
DEPENDENCY_UPDATE_BRANCH_PATTERN = 32
84+
"""Pattern of branches comprising dependency updates (e.g. dependabot)."""
5585
DEPENDENCY_UPDATE_NEWS_MESSAGE = 33
86+
"""Pattern of the news message for dependency update."""
5687
DEPENDENCY_UPDATE_NEWS_TYPE = 34
88+
"""News file type for dependency update."""
5789

5890
@staticmethod
5991
def choices() -> List[str]:

continuous_delivery_scripts/utils/language_specifics_base.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def get_related_language(self) -> str:
4949
"""Gets the name of the corresponding language."""
5050
pass
5151

52+
def get_version_tag(self, version: str) -> str:
53+
"""Generates a tag based on the version string."""
54+
return version
55+
5256
def generate_source_licence_header_template(self) -> str:
5357
"""Generates the template of the licence header which is put at the top of source files."""
5458
return _generate_generic_licence_header_template()
@@ -68,15 +72,15 @@ def generate_code_documentation(self, output_directory: Path, module_to_document
6872
pass
6973

7074
@abstractmethod
71-
def package_software(self) -> None:
75+
def package_software(self, version: str) -> None:
7276
"""Package the software so that it can get released."""
73-
logger.info("Generating a release package")
77+
logger.info(f"Generating a release package [{version}]")
7478
pass
7579

7680
@abstractmethod
77-
def release_package_to_repository(self) -> None:
81+
def release_package_to_repository(self, version: str) -> None:
7882
"""Release the package to the official software repository."""
79-
logger.info("Uploading the package")
83+
logger.info(f"Uploading the package [{version}]")
8084
pass
8185

8286
@abstractmethod

0 commit comments

Comments
 (0)