Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve RC workflow: Enhanced validation and error handling in Makefile #270

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 44 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ ifeq ($(UNAME_S),Darwin)
SORT := $(shell if command -v gsort >/dev/null 2>&1; then echo 'gsort'; else echo 'sort'; fi)
endif

RELEASE_VERSION ?= $(shell curl -sL "https://pypi.org/pypi/leverage/json" | jq -r ".releases | keys[]" | $(SORT) -V | tail -n 1 | awk 'BEGIN{FS="."; OFS="."} {print $$1,$$2,$$3+1}' )rc1
RELEASE_VERSION ?= $(shell curl -sL "https://pypi.org/pypi/leverage/json" | jq -r ".releases | keys[]" | $(SORT) -V | tail -n 1 | awk 'BEGIN{FS="[.-]"} {if ($$4 ~ /^rc[0-9]+$$/) {rc=substr($$4,3)+1} else {rc=0}; print $$1"."$$2"."$$3"-rc"rc}')

help:
@echo 'Available Commands:'
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | $(SORT) | awk 'BEGIN {FS = ":.*?## "}; {printf " - \033[36m%-18s\033[0m %s\n", $$1, $$2}'

build-image: ## Build docker image for testing
docker build . -t ${LEVERAGE_TESTING_IMAGE}:${LEVERAGE_TESTING_TAG}

test-unit: ## Run unit tests and create a coverage report
docker run --rm --privileged --mount type=bind,src=$(shell pwd),dst=/leverage -t ${LEVERAGE_TESTING_IMAGE}:${LEVERAGE_TESTING_TAG} pytest --verbose --cov=./ --cov-report=xml

Expand Down Expand Up @@ -64,26 +64,59 @@ push-test: ## Push distributables to Pypi test
bump-test-version: ## Bump version based on PyPI latest release or provided input
@echo "[INFO] Get current version from leverage/__init__.py"
$(eval CURRENT_VERSION=$(shell awk '/__version__/ {print $$3}' $(INIT_FILE) | tr -d '"' | tr -d "'"))
@echo "[INFO] Current version: $(CURRENT_VERSION)"
@echo "[INFO] Current version from project files: $(CURRENT_VERSION)"

@echo "[INFO] Fetching the latest version from PyPI."
$(eval LATEST_VERSION=$(shell curl -sL "https://pypi.org/pypi/leverage/json" | jq -r ".releases | keys[]" | $(SORT) -V | tail -n 1))
@echo "[INFO] Latest version fetched from PyPI: $(LATEST_VERSION)"

# Get the latest RC version from PyPI if it exists
$(eval LATEST_RC_VERSION=$(shell curl -sL "https://pypi.org/pypi/leverage/json" | jq -r ".releases | keys[]" | grep "$(LATEST_VERSION)-rc" | $(SORT) -V | tail -n 1))
Comment on lines +69 to +74
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the time of writing this comment:

$ curl -sL "https://pypi.org/pypi/leverage/json" | jq -r '.releases | keys[]' | sort -V | tail -n 2
1.12.3
1.12.3rc1

And so, after running these two statements

LATEST_VERSION=1.12.3rc1
LATEST_RC_VERSION=""

since rcs currently do not use the dash separator. But if we ignore this, both variables would hold the same value.
Suppose we don't have 1.12.3rc1 as a released version, we would end up with something like

LATEST_VERSION=1.12.3
LATEST_RC_VERSION=1.12.2rc3

which would create various different issues down the line like attempting to release 1.12.3rc4 without the previous 3 existing (following the logic in lines 77 to 83).

Couldn't we rely only on LATEST_VERSION?


ifeq ($(strip $(RELEASE_VERSION)),)
@echo "[INFO] RELEASE_VERSION not provided or empty. Fetching from TestPyPI."
$(eval LATEST_VERSION=$(shell curl -sL "https://pypi.org/pypi/leverage/json" | jq -r ".releases | keys[]" | $(SORT) -V | tail -n 1 ))
@echo "[INFO] Latest version fetched: $(LATEST_VERSION)"
$(eval RELEASE_VERSION=$(shell echo $(LATEST_VERSION) | awk 'BEGIN{FS="."; OFS="."} {sub("rc[0-9]+", "", $$3); print $$1,$$2,$$3+1 "rc1"}'))
@echo "[INFO] Auto-generated RELEASE_VERSION: $(RELEASE_VERSION)"
@echo "[INFO] RELEASE_VERSION not provided. Generating new RC version."
$(eval BASE_VERSION=$(shell echo $(LATEST_VERSION) | awk 'BEGIN{FS="-"} {print $$1}'))
$(eval RC_VERSION=$(shell echo $(LATEST_RC_VERSION) | awk 'BEGIN{FS="-rc"} {if (NF > 1) {print $$2} else {print "0"}}'))
$(eval NEXT_RC_VERSION=$(shell echo $(RC_VERSION) | awk '{print $$1+1}'))
$(eval RELEASE_VERSION=$(BASE_VERSION)-rc$(NEXT_RC_VERSION))
@echo "[INFO] Current version from PyPI: $(LATEST_VERSION)"
@echo "[INFO] Creating new RC version: $(RELEASE_VERSION)"
else
@echo "[INFO] RELEASE_VERSION provided as argument: $(RELEASE_VERSION)"
@echo "[INFO] Checking if provided RELEASE_VERSION is valid..."
$(eval PROVIDED_BASE_VERSION=$(shell echo $(RELEASE_VERSION) | awk 'BEGIN{FS="-"} {print $$1}'))
$(eval PROVIDED_RC_VERSION=$(shell echo $(RELEASE_VERSION) | awk 'BEGIN{FS="-rc"} {if (NF > 1) {print $$2} else {print "0"}}'))
@echo "[INFO] Current base version from PyPI: $(LATEST_VERSION)"
@echo "[INFO] Provided base version: $(PROVIDED_BASE_VERSION)"
@echo "[INFO] Provided RC version: $(PROVIDED_RC_VERSION)"
@echo "[INFO] Latest RC version from PyPI: $(LATEST_RC_VERSION)"
@if [ -z "$(LATEST_RC_VERSION)" ]; then \
if [ "$(PROVIDED_RC_VERSION)" != "0" ]; then \
echo "[ERROR] Provided RC version is invalid as there are no existing RC versions in PyPI. Exiting..."; \
exit 1; \
else \
echo "[INFO] Provided RC version is valid."; \
fi \
else \
if [ "$(PROVIDED_RC_VERSION)" -le "$(shell echo $(LATEST_RC_VERSION) | sed 's/.*-rc//')" ]; then \
echo "[INFO] Provided RC version is valid."; \
else \
echo "[ERROR] Provided RC version is invalid as it does not follow the latest RC version from PyPI. Exiting..."; \
exit 1; \
Comment on lines +101 to +105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By accepting PROVIDED_RC_VERSIONs that are lesser or equal that the current latest rc version we will most likely clash with an already existing release, wouldn't we? also we wouldn't be able to progress in the rcs version if I'm not mistaken.
I think rcs should be always incrementing in version number since they are for testing purposes, what do you think about it?

fi \
fi
endif

@echo "[INFO] Checking Release Version (template 9.9.9-rc9)..."
@echo "[INFO] Testing version syntax patterns..."
@echo $(RELEASE_VERSION) | awk '/^[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+$$/ {print "[INFO] Version ok"}' || (echo "[ERROR] Invalid format for RELEASE_VERSION. Expected format: ^[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+$$" && exit 1)

@echo "[INFO] Bump version to $(RELEASE_VERSION)"
@echo "[INFO] Bumping RC version to $(RELEASE_VERSION)"
@$(SED) -i 's/__version__ = "$(CURRENT_VERSION)"/__version__ = "$(RELEASE_VERSION)"/' $(INIT_FILE)
@$(SED) -i 's/version = "$(CURRENT_VERSION)"/version = "$(RELEASE_VERSION)"/' $(PYPROJECT_FILE)

bump-version-ci: ## Fetch latest tag, update versions in __init__.py and pyproject.toml
@echo "[INFO] Get latest tag"
$(eval RELEASE_VERSION=$(shell git fetch --all --tags && git tag --sort=version:refname | tail -1 | sed 's/v//'))
$(eval RELEASE_VERSION=$(shell git fetch --all --tags && git tag --sort=version:refname | tail -n 1 | sed 's/v//'))
@echo $(RELEASE_VERSION)

@echo "[INFO] Write version to __init__.py"
Expand Down
Loading