Skip to content

Commit

Permalink
chore: Add environment variable check script (#126)
Browse files Browse the repository at this point in the history
# Pull Request

## Description

This change introduces a new Python script to check for required
environment variables before the main execution. The script
`check_environment_variables.py` is added to verify the presence of
essential environment variables like `github_token` and
`INPUT_REPOSITORY_OWNER`.

The Dockerfile is updated to copy the new Python script and its
`__init__.py` file to the root directory. The `run.sh` script now
includes a step to execute this environment variable check before
proceeding with the main execution.

The Justfile is modified to include the new `python_scripts` directory
in the ruff linting and formatting commands, ensuring code quality for
the new additions.

In the `pyproject.toml` file, a new rule is added to ignore the T201
(print statement) warning for files in the `python_scripts` directory,
as printing is intentional for error reporting in the new script.

These changes enhance the robustness of the execution environment by
ensuring that all necessary variables are set before running the main
process.

fixes #125
  • Loading branch information
JackPlowman authored Oct 5, 2024
1 parent 3ff9743 commit 2596b6f
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 130 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ RUN mkdir -p /statistics && \

COPY --chmod=755 run.sh run.sh
COPY analyser analyser
COPY __init__.py python_scripts/check_environment_variables.py /

COPY --from=builder requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
Expand Down
5 changes: 5 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ docker-build:

docker-run:
docker run \
--env github_token=${GITHUB_TOKEN} \
--env INPUT_REPOSITORY_OWNER=JackPlowman \
--volume "$(pwd)/statistics:/statistics" \
--volume "$(pwd)/cloned_repositories:/cloned_repositories" \
Expand All @@ -68,15 +69,19 @@ ruff-fix:

ruff-lint:
poetry run ruff check analyser
poetry run ruff check python_scripts

ruff-lint-fix:
poetry run ruff check analyser --fix
poetry run ruff check python_scripts --fix

ruff-format:
poetry run ruff format --check analyser
poetry run ruff format --check python_scripts

ruff-format-fix:
poetry run ruff format analyser
poetry run ruff format python_scripts

# ------------------------------------------------------------------------------
# Other Python Tools
Expand Down
15 changes: 4 additions & 11 deletions analyser/utils/github_interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,10 @@ def retrieve_repositories() -> PaginatedList[Repository]:
Returns:
PaginatedList[Repository]: The list of repositories.
"""
repository_owner = getenv("INPUT_REPOSITORY_OWNER", "")
if repository_owner == "":
msg = "repository_owner environment variable is not set."
raise ValueError(msg)
token = getenv("github_token", "")
if token == "":
github = Github()
logger.debug("Using unauthenticated GitHub API")
else:
github = Github(token)
logger.debug("Using authenticated GitHub API")
repository_owner = getenv("INPUT_REPOSITORY_OWNER")
token = getenv("INPUT_GITHUB_TOKEN")
github = Github(token)
logger.debug("Using authenticated GitHub API")
repositories = github.search_repositories(query=f"user:{repository_owner} archived:false")
logger.info(
"Found repositories",
Expand Down
36 changes: 2 additions & 34 deletions analyser/utils/tests/test_github_interactions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from unittest.mock import MagicMock, call, patch

import pytest

from analyser.utils.github_interactions import clone_repo, retrieve_repositories

FILE_PATH = "analyser.utils.github_interactions"
Expand Down Expand Up @@ -34,24 +32,7 @@ def test_clone_repo_exists(mock_repo: MagicMock, mock_path: MagicMock) -> None:

@patch(f"{FILE_PATH}.Github")
@patch(f"{FILE_PATH}.getenv")
def test_retrieve_repositories__unauthenticated(mock_getenv: MagicMock, mock_github: MagicMock) -> None:
# Arrange
mock_getenv.side_effect = ["Test", ""]
full_name = "Test1/Test2"
mock_github.return_value.search_repositories.return_value = search_return = MagicMock(
totalCount=1, list=[MagicMock(full_name=full_name)]
)
# Act
repositories = retrieve_repositories()
# Assert
mock_github.assert_called_once_with()
mock_getenv.assert_has_calls([call("INPUT_REPOSITORY_OWNER", ""), call("github_token", "")])
assert repositories == search_return


@patch(f"{FILE_PATH}.Github")
@patch(f"{FILE_PATH}.getenv")
def test_retrieve_repositories__authenticated(mock_getenv: MagicMock, mock_github: MagicMock) -> None:
def test_retrieve_repositories(mock_getenv: MagicMock, mock_github: MagicMock) -> None:
# Arrange
token = "TestToken" # noqa: S105
mock_getenv.side_effect = ["Test", token]
Expand All @@ -63,18 +44,5 @@ def test_retrieve_repositories__authenticated(mock_getenv: MagicMock, mock_githu
repositories = retrieve_repositories()
# Assert
mock_github.assert_called_once_with(token)
mock_getenv.assert_has_calls([call("INPUT_REPOSITORY_OWNER", ""), call("github_token", "")])
mock_getenv.assert_has_calls([call("INPUT_REPOSITORY_OWNER"), call("INPUT_GITHUB_TOKEN")])
assert repositories == search_return


@patch(f"{FILE_PATH}.Github")
@patch(f"{FILE_PATH}.getenv")
def test_retrieve_repositories__no_repository_owner(mock_getenv: MagicMock, mock_github: MagicMock) -> None:
# Arrange
mock_getenv.return_value = ""
# Act
with pytest.raises(ValueError, match="repository_owner environment variable is not set."):
retrieve_repositories()
# Assert
mock_github.assert_not_called()
mock_getenv.assert_called_once_with("INPUT_REPOSITORY_OWNER", "")
162 changes: 81 additions & 81 deletions poetry.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pandas = "2.2.3"
[tool.poetry.group.dev.dependencies]
pytest = "8.3.3"
pytest-cov = "5.0.0"
ruff = "0.6.8"
vulture = "2.12"
check-jsonschema = "0.29.2"
ruff = "0.6.9"
vulture = "2.13"
check-jsonschema = "0.29.3"

[build-system]
requires = ["poetry-core"]
Expand Down Expand Up @@ -70,6 +70,7 @@ dummy-variable-rgx = "(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.lint.per-file-ignores]
"**test_*.py" = ["S101", "D102", "D103", "SLF001", "PT019"]
"python_scripts/*.py" = ["T201"]

[tool.ruff.lint.pydocstyle]
convention = "google" # Use Google docstring convention.
Expand Down
Empty file added python_scripts/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions python_scripts/check_environment_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from os import getenv
from sys import exit

EXPECTED_ENVIRONMENT_VARIABLES = ["INPUT_GITHUB_TOKEN", "INPUT_REPOSITORY_OWNER"]

for variable in EXPECTED_ENVIRONMENT_VARIABLES:
if getenv(variable) is None:
if "INPUT_" in variable:
print(f'Error: Required environment variable {variable.removeprefix("INPUT_")} is not set')
else:
print(f"Error: Required environment variable {variable} is not set")
exit(1)
3 changes: 3 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ if [ "$CI" = "true" ]; then
cd ..
fi

# Check that the required environment variables are set
python check_environment_variables.py

# Run the analyser
python -m analyser

Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ sonar.sources=.
sonar.python.version=3.12
sonar.python.coverage.reportPaths=coverage.xml

sonar.coverage.exclusions=**/tests/**
sonar.coverage.exclusions=**/tests/**,python_scripts/check_environment_variables.py
sonar.test.exclusions=**/tests/**

0 comments on commit 2596b6f

Please sign in to comment.