From 4a12a729a7853fb0f86b7805d636e30072585a7c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 14:36:29 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=96=20From=20test=20=E2=86=92=20Bump?= =?UTF-8?q?=20version:=20v1.1.20-test=20into=20prod=20(#117)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatically created pull request for release v1.1.20-test into prod branch. Signed-off-by: dependabot[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Juan Villa Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .bumpversion.cfg | 2 +- .github/workflows/version-controller.yml | 11 ++-- CHANGELOG.md | 14 +++++ generate_changelog/main.py | 5 +- pyproject.toml | 10 +-- validate_container_names/main.py | 80 ++++++++++++++++++++++++ validate_docker_compose/main.py | 4 +- 7 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 validate_container_names/main.py diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 68536e2..86a4f23 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.1.19 +current_version = 1.1.20 commit = True tag = False diff --git a/.github/workflows/version-controller.yml b/.github/workflows/version-controller.yml index 816b1d6..41d917b 100644 --- a/.github/workflows/version-controller.yml +++ b/.github/workflows/version-controller.yml @@ -97,14 +97,17 @@ jobs: VERSION=${{ steps.get_version.outputs.current_version }} BRANCH_NAME=${{ steps.determine_branch.outputs.current_branch }} TAG_NAME="v${VERSION}-${BRANCH_NAME}" - git tag "$TAG_NAME" + if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then + echo "Tag $TAG_NAME already exists — skipping creation" + else + git tag "$TAG_NAME" + fi echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT - continue-on-error: true - name: Push Tag id: push_tag - if: steps.check_arrow.outputs.contains_arrow == 'true' + if: steps.check_arrow.outputs.contains_arrow == 'true' && steps.create_tag.outputs.tag_name != '' run: | - git push origin "${{ steps.create_tag.outputs.tag_name }}" + git push origin "${{ steps.create_tag.outputs.tag_name }}" || echo "Tag already on remote — skipping" - name: Ensure on Current Branch id: ensure_branch if: steps.check_arrow.outputs.contains_arrow == 'true' diff --git a/CHANGELOG.md b/CHANGELOG.md index a82aaf9..387ab21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## [1.1.19] - 2026-03-03 + +### Features + +- **core**: add inline release creation to version controller (`patch candidate`) + +### Bug Fixes + +- **core**: add pull-requests write permission to version controller (`patch candidate`) + +### Documentation + +- **core**: update changelog + ## [1.1.17] - 2026-03-03 ### Bug Fixes diff --git a/generate_changelog/main.py b/generate_changelog/main.py index 2f14c2e..9923b84 100644 --- a/generate_changelog/main.py +++ b/generate_changelog/main.py @@ -115,8 +115,9 @@ def fetch_tags() -> None: subprocess.check_output(["git", "fetch", "--tags"]) logger.info("Successfully fetched Git tags.") except subprocess.CalledProcessError as error: - logger.error(f"Error fetching Git tags: {error}") - raise + logger.warning( + f"Could not fetch Git tags from remote (continuing with local tags): {error}" + ) def parse_version(version_str: str) -> Tuple[int, int, int]: diff --git a/pyproject.toml b/pyproject.toml index 6368976..badc6d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "scripts" -version = "1.1.19" +version = "1.1.20" description = "CICD Core Scripts" authors = ["B "] license = "GLPv3" @@ -9,13 +9,13 @@ package-mode = false [tool.poetry.dependencies] python = "^3.12" -setuptools = "^82.0.0" +setuptools = "^82.0.1" idna = "^3.0" certifi = "^2026.1.4" -bump2version = "^1.0.0" +bump2version = "^1.0.1" python-dotenv = "^1.0.0" cryptography = "^46.0.5" -requests = "^2.32.3" +requests = "^2.34.2" wheel = ">=0.36.2" [tool.poetry.group.dev.dependencies] @@ -25,7 +25,7 @@ yamllint="^1.35.0" isort = "^6.0.1" toml = "^0.10.0" black = "^26.1.0" -pytest = "^8.3.1" +pytest = "^9.0.3" httpx = { version = ">=0.24.0", optional = true } pytest-cov = "^6.0.0" coverage = "^7.2.5" diff --git a/validate_container_names/main.py b/validate_container_names/main.py new file mode 100644 index 0000000..d3934aa --- /dev/null +++ b/validate_container_names/main.py @@ -0,0 +1,80 @@ +# scripts/validate_container_names/main.py + +import re +import sys +import os + +# Container template naming convention: Container{SUITE}{APP}{ENV}.yml +# Rules: +# - Must start with literal "Container" +# - Followed by SUITE+APP in uppercase alphanumeric (min 2 chars) +# - Must end with exactly one environment suffix: PROD | TEST | DEV +# - Extension must be .yml +VALID_ENVS = ("PROD", "TEST", "DEV") +CONTAINER_NAME_REGEX = re.compile(r"^Container[A-Z0-9]{2,}(?:PROD|TEST|DEV)\.yml$") + + +def validate_filename(file_path): + """ + Validate that a CloudFormation template filename follows the convention: + Container{SUITE}{APP}{ENV}.yml + + Args: + :param file_path: Path to the CloudFormation template file + :returns: True if valid, False otherwise + """ + basename = os.path.basename(file_path) + + if not CONTAINER_NAME_REGEX.match(basename): + env_hint = " | ".join(VALID_ENVS) + print( + f"[ERROR] '{basename}' does not follow the naming convention.\n" + f" Expected: Container{{SUITE}}{{APP}}{{{env_hint}}}.yml\n" + f" Rules:\n" + f" - Must start with 'Container'\n" + f" - SUITE and APP must be uppercase alphanumeric (no hyphens, underscores or spaces)\n" + f" - Must end with one of: {env_hint}\n" + f" - Extension must be .yml\n" + f" Example: ContainerGESTIONATENCIONBACKPROD.yml" + ) + return False + + # Extract the env suffix for informational output + name_no_ext = basename[: -len(".yml")] + env = next(e for e in VALID_ENVS if name_no_ext.endswith(e)) + suite_app = name_no_ext[len("Container") : -len(env)] + print(f"[OK] '{basename}' — suite+app: '{suite_app}', env: '{env}'") + return True + + +def main(): + """Main function for validating Container CloudFormation template filenames.""" + + if len(sys.argv) < 2: + print("[ERROR] Incorrect usage. Must specify at least one file.") + sys.exit(1) + + files = sys.argv[1:] + errors = [] + + for file in files: + if not validate_filename(file): + errors.append(os.path.basename(file)) + + if errors: + print(f"\n[FAIL] {len(errors)} file(s) with invalid names: {', '.join(errors)}") + sys.exit(1) + + print(f"[OK] All {len(files)} file(s) passed naming validation.") + sys.exit(0) + + +if __name__ == "__main__": + if sys.stdout.encoding.lower() != "utf-8": + try: + sys.stdout.reconfigure(encoding="utf-8") + except AttributeError: + import io + + sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") + main() diff --git a/validate_docker_compose/main.py b/validate_docker_compose/main.py index 0cacdbb..e875e7c 100644 --- a/validate_docker_compose/main.py +++ b/validate_docker_compose/main.py @@ -40,7 +40,7 @@ def validate_docker_compose(file_path): """ try: result = subprocess.run( - ["docker-compose", "-f", file_path, "config"], + ["docker", "compose", "-f", file_path, "config"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -54,7 +54,7 @@ def validate_docker_compose(file_path): print(e.stderr) sys.exit(1) except FileNotFoundError: - print("[ERROR] docker-compose not found.") + print("[ERROR] docker compose not found.") sys.exit(1)