Loading .gitlab-ci.yml +25 −192 Original line number Diff line number Diff line # software-di-controllo/.gitlab-ci.yml image: python:3.12 variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" LINT_FORMAT_TARGETS: "noctua" PYLINT_TARGETS: "noctua" # For auto-committing (use with caution) GIT_USER_EMAIL: "gitlab-ci@yourdomain.com" # Configure as appropriate GIT_USER_NAME: "GitLab CI" TESTED_BRANCH_NAME: "ci-auto-formatted" # Name of the branch for auto-commits cache: key: "$CI_COMMIT_REF_SLUG" paths: - .cache/pip # If you decide to use a venv within jobs, cache it here too # - venv/ stages: - setup_project # Just installs the project itself for context - lint_and_format - auto_commit_changes # New stage for committing # - test # - build # - deploy # Job to install the project itself (so linters understand its structure) install_project_context: stage: setup_project tags: - git-run-ia2 script: - echo "Python version:" - python -V - pip install --upgrade pip - echo "Installing project 'noctua' in editable mode..." - pip install -e . # Install project and its dependencies - echo "Project setup complete." # No artifacts needed here if subsequent jobs handle their own tool installations # and re-checkout the code (which GitLab runners typically do by default for each job) isort_check: # Renamed to just check, formatting applied locally is preferred stage: lint_and_format tags: - git-run-ia2 # 'needs' or 'dependencies' not strictly needed if this job checks out code and installs tools before_script: - pip install isort script: - echo "Checking import order with isort..." - isort --check-only --diff ${LINT_FORMAT_TARGETS} - echo "isort check complete." rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true style_check_code: # Renamed to just check stage: lint_and_format tags: - git-run-ia2 before_script: - pip install autopep8 # Or black if you switch script: - echo "Checking code style with autopep8..." - autopep8 --diff --recursive ${LINT_FORMAT_TARGETS} > autopep8.diff || true - | if [ -s autopep8.diff ]; then echo "autopep8 found style issues that would be applied. Diff:" cat autopep8.diff echo "Please run 'autopep8 --in-place --recursive ${LINT_FORMAT_TARGETS}' locally and commit changes." # exit 1 # Fail the job if diff is not empty else echo "autopep8: No style changes needed." fi artifacts: when: on_failure # Capture diff only if the check "fails" (if you uncomment exit 1) or always paths: - autopep8.diff rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true delete_trailing_whitespaces_check: # Renamed to just check stage: lint_and_format tags: - git-run-ia2 script: - echo "Checking for trailing whitespaces..." - | TRAILING_WHITESPACE_FILES=$(find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec grep -lE "[[:space:]]+$" {} \;) if [ -n "$TRAILING_WHITESPACE_FILES" ]; then echo "ERROR: Trailing whitespaces found in the following files:" echo "$TRAILING_WHITESPACE_FILES" echo "Please remove them locally and commit changes." # exit 1 # Fail the job else echo "No trailing whitespaces found." fi rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true pylint_code_quality: stage: lint_and_format tags: - git-run-ia2 before_script: - pip install pylint # Crucially, install the project itself so pylint can resolve its imports - pip install -e . script: - echo "Running pylint code quality check on '${PYLINT_TARGETS}'..." - pylint --rcfile=.pylintrc ${PYLINT_TARGETS} - echo "Pylint check complete." rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true # New job to apply formatting and commit to a new branch # WARNING: Auto-committing from CI can be risky. Use with extreme caution. # Ensure your runner has SSH keys configured if pushing to a protected branch or using HTTPS with tokens. apply_format_and_commit: stage: auto_commit_changes tags: - git-run-ia2 # This job should run only if the developer explicitly wants it, # e.g., on a specific trigger or manually. Not typically on every MR. # Or, run it on a feature branch but not directly to main. # For this example, let's make it manual and only on the default branch as a starting point. rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual # Make it a manual action allow_failure: false # If it runs, it should succeed or clearly fail # In commit_formatted_changes job before_script: - pip install isort autopep8 # Or black - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )' - eval $(ssh-agent -s) # IMPORTANT: Add your deploy key (with write access) to the agent # This key should be stored as a CI/CD variable (type: File) # Example: Name: SSH_DEPLOY_KEY, Value: (paste private key here) # - echo "$SSH_DEPLOY_KEY" | tr -d '\r' | ssh-add - # If using HTTPS with a token: # - git config --global user.email "${GIT_USER_EMAIL}" # - git config --global user.name "${GIT_USER_NAME}" # - git remote set-url origin "https://oauth2:${GITLAB_TOKEN}@${CI_REPOSITORY_URL#*@}" # (GITLAB_TOKEN would be a project access token with write_repository scope) # For SSH (more common for CI write access): - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo "$SSH_DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_ed25519_ci_deploy # Or id_rsa - chmod 600 ~/.ssh/id_ed25519_ci_deploy - ssh-add ~/.ssh/id_ed25519_ci_deploy - 'ssh-keyscan -p $CI_SERVER_PORT $CI_SERVER_HOST >> ~/.ssh/known_hosts' # $CI_SERVER_PORT might not be needed for standard ssh - chmod 644 ~/.ssh/known_hosts # Configure Git user - git config --global user.email "${GIT_USER_EMAIL}" - git config --global user.name "${GIT_USER_NAME}" # Check out the current branch code # ... (SSH and git config setup) ... - git checkout "$CI_COMMIT_BRANCH" - git pull origin "$CI_COMMIT_BRANCH" # Ensure we have the latest - git pull origin "$CI_COMMIT_BRANCH" --ff-only # Get latest from triggering branch # Install formatters AGAIN in this job to ensure they run on the clean checkout - pip install isort autopep8 script: - echo "Applying isort formatting..." - isort ${LINT_FORMAT_TARGETS} - echo "Applying autopep8 formatting..." - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - echo "Removing trailing whitespaces..." - echo "Re-applying all formatting for commit accuracy..." - find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - isort ${LINT_FORMAT_TARGETS} - echo "Checking for formatting changes to commit..." - | # Check if there are any changes if ! git diff --quiet; then echo "Code formatting changes detected. Committing to new branch '${TESTED_BRANCH_NAME}'." git checkout -B "${TESTED_BRANCH_NAME}" # Create/switch to the new branch git add ${LINT_FORMAT_TARGETS} # Add specific targets or '.' for all changes if ! git diff --quiet HEAD; then # Compare working tree with HEAD echo "Code formatting changes applied. Committing to new branch '${FORMATTED_BRANCH_NAME}'." git checkout -B "${FORMATTED_BRANCH_NAME}" # Create new branch from current HEAD git add ${LINT_FORMAT_TARGETS} # Stage the changes made by formatters in this job git commit -m "ci: Apply automated code formatting [skip ci]" # Pushing to a new branch is safer than pushing to the original branch # The runner needs push permissions. git push origin "${TESTED_BRANCH_NAME}" -o ci.skip # Use -o ci.skip if supported to prevent triggering another pipeline echo "Changes pushed to branch '${TESTED_BRANCH_NAME}'." echo "Please review and merge '${TESTED_BRANCH_NAME}' into '${CI_COMMIT_BRANCH}'." echo "Pushing changes to branch '${FORMATTED_BRANCH_NAME}'..." git push -u origin "${FORMATTED_BRANCH_NAME}" -o ci.skip echo "Changes pushed. Please review and merge '${FORMATTED_BRANCH_NAME}'." else echo "No formatting changes to commit." fi Loading
.gitlab-ci.yml +25 −192 Original line number Diff line number Diff line # software-di-controllo/.gitlab-ci.yml image: python:3.12 variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" LINT_FORMAT_TARGETS: "noctua" PYLINT_TARGETS: "noctua" # For auto-committing (use with caution) GIT_USER_EMAIL: "gitlab-ci@yourdomain.com" # Configure as appropriate GIT_USER_NAME: "GitLab CI" TESTED_BRANCH_NAME: "ci-auto-formatted" # Name of the branch for auto-commits cache: key: "$CI_COMMIT_REF_SLUG" paths: - .cache/pip # If you decide to use a venv within jobs, cache it here too # - venv/ stages: - setup_project # Just installs the project itself for context - lint_and_format - auto_commit_changes # New stage for committing # - test # - build # - deploy # Job to install the project itself (so linters understand its structure) install_project_context: stage: setup_project tags: - git-run-ia2 script: - echo "Python version:" - python -V - pip install --upgrade pip - echo "Installing project 'noctua' in editable mode..." - pip install -e . # Install project and its dependencies - echo "Project setup complete." # No artifacts needed here if subsequent jobs handle their own tool installations # and re-checkout the code (which GitLab runners typically do by default for each job) isort_check: # Renamed to just check, formatting applied locally is preferred stage: lint_and_format tags: - git-run-ia2 # 'needs' or 'dependencies' not strictly needed if this job checks out code and installs tools before_script: - pip install isort script: - echo "Checking import order with isort..." - isort --check-only --diff ${LINT_FORMAT_TARGETS} - echo "isort check complete." rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true style_check_code: # Renamed to just check stage: lint_and_format tags: - git-run-ia2 before_script: - pip install autopep8 # Or black if you switch script: - echo "Checking code style with autopep8..." - autopep8 --diff --recursive ${LINT_FORMAT_TARGETS} > autopep8.diff || true - | if [ -s autopep8.diff ]; then echo "autopep8 found style issues that would be applied. Diff:" cat autopep8.diff echo "Please run 'autopep8 --in-place --recursive ${LINT_FORMAT_TARGETS}' locally and commit changes." # exit 1 # Fail the job if diff is not empty else echo "autopep8: No style changes needed." fi artifacts: when: on_failure # Capture diff only if the check "fails" (if you uncomment exit 1) or always paths: - autopep8.diff rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true delete_trailing_whitespaces_check: # Renamed to just check stage: lint_and_format tags: - git-run-ia2 script: - echo "Checking for trailing whitespaces..." - | TRAILING_WHITESPACE_FILES=$(find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec grep -lE "[[:space:]]+$" {} \;) if [ -n "$TRAILING_WHITESPACE_FILES" ]; then echo "ERROR: Trailing whitespaces found in the following files:" echo "$TRAILING_WHITESPACE_FILES" echo "Please remove them locally and commit changes." # exit 1 # Fail the job else echo "No trailing whitespaces found." fi rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true pylint_code_quality: stage: lint_and_format tags: - git-run-ia2 before_script: - pip install pylint # Crucially, install the project itself so pylint can resolve its imports - pip install -e . script: - echo "Running pylint code quality check on '${PYLINT_TARGETS}'..." - pylint --rcfile=.pylintrc ${PYLINT_TARGETS} - echo "Pylint check complete." rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true # New job to apply formatting and commit to a new branch # WARNING: Auto-committing from CI can be risky. Use with extreme caution. # Ensure your runner has SSH keys configured if pushing to a protected branch or using HTTPS with tokens. apply_format_and_commit: stage: auto_commit_changes tags: - git-run-ia2 # This job should run only if the developer explicitly wants it, # e.g., on a specific trigger or manually. Not typically on every MR. # Or, run it on a feature branch but not directly to main. # For this example, let's make it manual and only on the default branch as a starting point. rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual # Make it a manual action allow_failure: false # If it runs, it should succeed or clearly fail # In commit_formatted_changes job before_script: - pip install isort autopep8 # Or black - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )' - eval $(ssh-agent -s) # IMPORTANT: Add your deploy key (with write access) to the agent # This key should be stored as a CI/CD variable (type: File) # Example: Name: SSH_DEPLOY_KEY, Value: (paste private key here) # - echo "$SSH_DEPLOY_KEY" | tr -d '\r' | ssh-add - # If using HTTPS with a token: # - git config --global user.email "${GIT_USER_EMAIL}" # - git config --global user.name "${GIT_USER_NAME}" # - git remote set-url origin "https://oauth2:${GITLAB_TOKEN}@${CI_REPOSITORY_URL#*@}" # (GITLAB_TOKEN would be a project access token with write_repository scope) # For SSH (more common for CI write access): - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo "$SSH_DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_ed25519_ci_deploy # Or id_rsa - chmod 600 ~/.ssh/id_ed25519_ci_deploy - ssh-add ~/.ssh/id_ed25519_ci_deploy - 'ssh-keyscan -p $CI_SERVER_PORT $CI_SERVER_HOST >> ~/.ssh/known_hosts' # $CI_SERVER_PORT might not be needed for standard ssh - chmod 644 ~/.ssh/known_hosts # Configure Git user - git config --global user.email "${GIT_USER_EMAIL}" - git config --global user.name "${GIT_USER_NAME}" # Check out the current branch code # ... (SSH and git config setup) ... - git checkout "$CI_COMMIT_BRANCH" - git pull origin "$CI_COMMIT_BRANCH" # Ensure we have the latest - git pull origin "$CI_COMMIT_BRANCH" --ff-only # Get latest from triggering branch # Install formatters AGAIN in this job to ensure they run on the clean checkout - pip install isort autopep8 script: - echo "Applying isort formatting..." - isort ${LINT_FORMAT_TARGETS} - echo "Applying autopep8 formatting..." - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - echo "Removing trailing whitespaces..." - echo "Re-applying all formatting for commit accuracy..." - find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - isort ${LINT_FORMAT_TARGETS} - echo "Checking for formatting changes to commit..." - | # Check if there are any changes if ! git diff --quiet; then echo "Code formatting changes detected. Committing to new branch '${TESTED_BRANCH_NAME}'." git checkout -B "${TESTED_BRANCH_NAME}" # Create/switch to the new branch git add ${LINT_FORMAT_TARGETS} # Add specific targets or '.' for all changes if ! git diff --quiet HEAD; then # Compare working tree with HEAD echo "Code formatting changes applied. Committing to new branch '${FORMATTED_BRANCH_NAME}'." git checkout -B "${FORMATTED_BRANCH_NAME}" # Create new branch from current HEAD git add ${LINT_FORMAT_TARGETS} # Stage the changes made by formatters in this job git commit -m "ci: Apply automated code formatting [skip ci]" # Pushing to a new branch is safer than pushing to the original branch # The runner needs push permissions. git push origin "${TESTED_BRANCH_NAME}" -o ci.skip # Use -o ci.skip if supported to prevent triggering another pipeline echo "Changes pushed to branch '${TESTED_BRANCH_NAME}'." echo "Please review and merge '${TESTED_BRANCH_NAME}' into '${CI_COMMIT_BRANCH}'." echo "Pushing changes to branch '${FORMATTED_BRANCH_NAME}'..." git push -u origin "${FORMATTED_BRANCH_NAME}" -o ci.skip echo "Changes pushed. Please review and merge '${FORMATTED_BRANCH_NAME}'." else echo "No formatting changes to commit." fi