Loading .gitlab-ci.yml +167 −47 Original line number Diff line number Diff line # .gitlab-ci.yml image: python:3.12 variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" LINT_FORMAT_TARGETS: "noctua" PYLINT_TARGETS: "noctua" # We will apply formatting only to the 'noctua' package directory FORMAT_TARGETS: "noctua" # For sed, autopep8, isort PYLINT_TARGETS: "noctua" # For pylint # Git user for potential auto-commits (if added later) GIT_USER_EMAIL: "davide.ricci@inaf.it" GIT_USER_NAME: "Davide GitLab CI" FORMATTED_BRANCH_NAME: "ci-auto-formatted" # Branch for auto-committed changes # Branch for auto-committed changes (if added later) # FORMATTED_BRANCH_NAME: "ci-auto-formatted" cache: key: "$CI_COMMIT_REF_SLUG" # Cache per branch key: "$CI_COMMIT_REF_SLUG" # Cache pip downloads per branch paths: - .cache/pip # If you were to use a venv consistently and wanted to cache it: # - venv/ stages: - setup - format_and_lint # Combined stage - auto_commit_if_changed - setup_and_format # A single stage to perform all modifications sequentially - lint # A stage for checks that don't modify code (like pylint) # - auto_commit # Optional stage for committing changes # Job to install tools and the project itself prepare_and_install: stage: setup # Job 1: Install Noctua and its dependencies install_noctua: stage: setup_and_format # Start of the sequential process tags: - git-run-ia2 - git-run-ia2 # Your runner tag script: - echo "Python version $(python -V)" - echo "Current directory $(pwd)" - ls -la - echo "Python version $(python -v)" - pip install --upgrade pip - pip install isort autopep8 pylint # Install the project in editable mode. This also installs its dependencies. # This makes the 'noctua' package available for subsequent steps if they # were to run python code that imports it, and for pylint to understand it. - echo "Installing project 'noctua' and its dependencies..." - pip install -e . - echo "Setup complete." - echo "Noctua installation complete." artifacts: paths: - . # Pass the whole workspace and project # Pass the entire workspace. This includes the checked-out code # and any environment changes if pip installed into a local venv (not default) # or if -e . modifies local files (e.g. .egg-info). - . # The current working directory state expire_in: 1 hour # --- Formatting and Linting Jobs (run sequentially using artifacts) --- apply_trailing_whitespace_fix: stage: format_and_lint # Job 2: Remove Trailing Whitespaces fix_trailing_whitespaces: stage: setup_and_format tags: - git-run-ia2 needs: - job: prepare_and_install artifacts: true - job: install_noctua # Depends on the initial checkout and project setup artifacts: true # Use the workspace from the previous job script: - echo "Removing trailing whitespaces from ${LINT_FORMAT_TARGETS}..." - find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; - echo "Trailing whitespaces removed." - echo "Current directory $(pwd)" - ls -la - echo "Removing trailing whitespaces from '${FORMAT_TARGETS}' directory..." # Ensure FORMAT_TARGETS (e.g., "noctua") exists - | if [ -d "${FORMAT_TARGETS}" ]; then find "${FORMAT_TARGETS}" -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; echo "Trailing whitespaces removed." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping whitespace removal." fi artifacts: paths: - noctua/ - . # Pass the modified workspace expire_in: 1 hour apply_autopep8_format: stage: format_and_lint # Job 3: Apply isort apply_isort: stage: setup_and_format tags: - git-run-ia2 needs: - job: apply_trailing_whitespace_fix - job: fix_trailing_whitespaces artifacts: true before_script: - pip install isort # Install isort in this job's environment script: - echo "Applying autopep8 formatting to ${LINT_FORMAT_TARGETS}..." - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - echo "autopep8 formatting complete." - echo "Current directory $(pwd)" - ls -la - echo "Applying isort to '${FORMAT_TARGETS}' directory..." # isort will use pyproject.toml for configuration if present in the workspace root - | if [ -d "${FORMAT_TARGETS}" ]; then isort "${FORMAT_TARGETS}" echo "isort formatting complete." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping isort." fi artifacts: paths: - noctua/ - . # Pass the modified workspace expire_in: 1 hour apply_isort_format: stage: format_and_lint # Job 4: Apply autopep8 apply_autopep8: stage: setup_and_format tags: - git-run-ia2 needs: - job: apply_autopep8_format - job: apply_isort artifacts: true before_script: - pip install autopep8 # Install autopep8 in this job's environment script: - echo "Applying isort import sorting to ${LINT_FORMAT_TARGETS}..." - isort ${LINT_FORMAT_TARGETS} - echo "isort complete." - echo "Current directory $(pwd)" - ls -la - echo "Applying autopep8 to '${FORMAT_TARGETS}' directory..." - | if [ -d "${FORMAT_TARGETS}" ]; then autopep8 --in-place --recursive --aggressive --aggressive "${FORMAT_TARGETS}" echo "autopep8 formatting complete." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping autopep8." fi artifacts: paths: - noctua/ - . # Pass the modified workspace (this is the fully formatted code) expire_in: 1 hour run_pylint_check: stage: format_and_lint # Job 5: Run Pylint run_pylint: stage: lint # Separate stage for non-modifying checks tags: - git-run-ia2 needs: - job: apply_isort_format - job: apply_autopep8 # Get the fully formatted code artifacts: true before_script: - pip install pylint # Crucially, also ensure the project itself is "installed" or accessible # for pylint to resolve its internal imports and dependencies. # If the artifact from apply_autopep8 doesn't guarantee a fully functional # python environment with noctua installed, we might need to `pip install -e .` again. # However, since install_noctua did `pip install -e .` and we pass the whole # workspace, the .egg-info or similar should be present, making `noctua` importable. # Let's assume the workspace artifact correctly sets up the Python path for `noctua`. # If pylint has import errors for 'noctua' or its submodules, add `pip install -e .` here. # Test: - echo "Ensuring noctua is importable for pylint..." - python -c "import noctua; print(f'Successfully imported noctua v{noctua.__version__}')" || \ (echo "Failed to import noctua, trying pip install -e ." && pip install -e . && \ python -c "import noctua; print(f'Successfully imported noctua v{noctua.__version__} after re-install')") script: - echo "Running pylint code quality check on '${PYLINT_TARGETS}'..." # .pylintrc should be at the project root, available from artifact # The `pip install -e .` in prepare_and_install ensures pylint can find 'noctua' - pylint --rcfile=.pylintrc ${PYLINT_TARGETS} - echo "Current directory $(pwd)" - ls -la - echo "Running pylint on '${PYLINT_TARGETS}'..." # .pylintrc should be at the project root, available from the artifact - pylint --rcfile=.pylintrc "${PYLINT_TARGETS}" - echo "Pylint check complete." # This job acts as a gate. If it fails, the pipeline stops here (unless allow_failure=true). # No file artifacts are typically produced by pylint itself. rules: # Standard rules to run on MRs and default branch - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true # Allow manual trigger to not fail overall pipeline if desired # --- Optional: Auto Commit Job (Add if you want CI to commit changes) --- # commit_formatted_code: # stage: auto_commit # tags: # - git-run-ia2 # needs: # - job: run_pylint # Must pass pylint # - job: apply_autopep8 # Needs the final code state from formatting # artifacts: true # before_script: # # Git and SSH setup (ensure SSH_DEPLOY_KEY CI/CD variable is set as File type) # - apt-get update -y && apt-get install -y openssh-client git # - eval $(ssh-agent -s) # - mkdir -p ~/.ssh && chmod 700 ~/.ssh # - echo "$SSH_DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_ci_deploy && chmod 600 ~/.ssh/id_ci_deploy # - ssh-add ~/.ssh/id_ci_deploy # - ssh-keyscan -p ${CI_SERVER_PORT:-22} $CI_SERVER_HOST >> ~/.ssh/known_hosts && chmod 644 ~/.ssh/known_hosts # - git config --global user.email "${GIT_USER_EMAIL}" # - git config --global user.name "${GIT_USER_NAME}" # # Ensure we are on the correct branch and have the latest files from artifacts # - git checkout "$CI_COMMIT_BRANCH" # script: # - echo "Checking for formatting changes to commit..." # - | # # Add only the formatted targets to avoid committing other unintended changes # git add "${FORMAT_TARGETS}" # # if ! git diff --cached --quiet HEAD; then # Check staged changes against HEAD # echo "Code formatting changes applied. Committing to branch '${CI_COMMIT_BRANCH}'." # # Option 1: Commit to a NEW branch (Safer) # # git checkout -B "${FORMATTED_BRANCH_NAME}" # # git commit -m "ci: Apply automated code formatting [skip ci]" # # git push -u origin "${FORMATTED_BRANCH_NAME}" -o ci.skip # # echo "Changes pushed to new branch '${FORMATTED_BRANCH_NAME}'. Please review and merge." # # # Option 2: Commit directly to the CURRENT branch (Use with extreme caution!) # # This is generally NOT recommended for branches that developers also work on directly. # # Only suitable if this CI job is the SOLE writer to this branch for formatting. # git commit -m "ci: Apply automated code formatting [skip ci]" # echo "Pushing formatting changes to '${CI_COMMIT_BRANCH}'..." # git push origin HEAD:"${CI_COMMIT_BRANCH}" -o ci.skip # Push current HEAD to remote branch # echo "Formatting changes pushed to '${CI_COMMIT_BRANCH}'." # else # echo "No formatting changes to commit." # fi # rules: # # Example: Only run manually on the default branch after all checks pass # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "schedule" # Avoid on schedules # when: manual # Make this a conscious decision # allow_failure: false # If it runs, it must succeed Loading
.gitlab-ci.yml +167 −47 Original line number Diff line number Diff line # .gitlab-ci.yml image: python:3.12 variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" LINT_FORMAT_TARGETS: "noctua" PYLINT_TARGETS: "noctua" # We will apply formatting only to the 'noctua' package directory FORMAT_TARGETS: "noctua" # For sed, autopep8, isort PYLINT_TARGETS: "noctua" # For pylint # Git user for potential auto-commits (if added later) GIT_USER_EMAIL: "davide.ricci@inaf.it" GIT_USER_NAME: "Davide GitLab CI" FORMATTED_BRANCH_NAME: "ci-auto-formatted" # Branch for auto-committed changes # Branch for auto-committed changes (if added later) # FORMATTED_BRANCH_NAME: "ci-auto-formatted" cache: key: "$CI_COMMIT_REF_SLUG" # Cache per branch key: "$CI_COMMIT_REF_SLUG" # Cache pip downloads per branch paths: - .cache/pip # If you were to use a venv consistently and wanted to cache it: # - venv/ stages: - setup - format_and_lint # Combined stage - auto_commit_if_changed - setup_and_format # A single stage to perform all modifications sequentially - lint # A stage for checks that don't modify code (like pylint) # - auto_commit # Optional stage for committing changes # Job to install tools and the project itself prepare_and_install: stage: setup # Job 1: Install Noctua and its dependencies install_noctua: stage: setup_and_format # Start of the sequential process tags: - git-run-ia2 - git-run-ia2 # Your runner tag script: - echo "Python version $(python -V)" - echo "Current directory $(pwd)" - ls -la - echo "Python version $(python -v)" - pip install --upgrade pip - pip install isort autopep8 pylint # Install the project in editable mode. This also installs its dependencies. # This makes the 'noctua' package available for subsequent steps if they # were to run python code that imports it, and for pylint to understand it. - echo "Installing project 'noctua' and its dependencies..." - pip install -e . - echo "Setup complete." - echo "Noctua installation complete." artifacts: paths: - . # Pass the whole workspace and project # Pass the entire workspace. This includes the checked-out code # and any environment changes if pip installed into a local venv (not default) # or if -e . modifies local files (e.g. .egg-info). - . # The current working directory state expire_in: 1 hour # --- Formatting and Linting Jobs (run sequentially using artifacts) --- apply_trailing_whitespace_fix: stage: format_and_lint # Job 2: Remove Trailing Whitespaces fix_trailing_whitespaces: stage: setup_and_format tags: - git-run-ia2 needs: - job: prepare_and_install artifacts: true - job: install_noctua # Depends on the initial checkout and project setup artifacts: true # Use the workspace from the previous job script: - echo "Removing trailing whitespaces from ${LINT_FORMAT_TARGETS}..." - find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; - echo "Trailing whitespaces removed." - echo "Current directory $(pwd)" - ls -la - echo "Removing trailing whitespaces from '${FORMAT_TARGETS}' directory..." # Ensure FORMAT_TARGETS (e.g., "noctua") exists - | if [ -d "${FORMAT_TARGETS}" ]; then find "${FORMAT_TARGETS}" -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \; echo "Trailing whitespaces removed." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping whitespace removal." fi artifacts: paths: - noctua/ - . # Pass the modified workspace expire_in: 1 hour apply_autopep8_format: stage: format_and_lint # Job 3: Apply isort apply_isort: stage: setup_and_format tags: - git-run-ia2 needs: - job: apply_trailing_whitespace_fix - job: fix_trailing_whitespaces artifacts: true before_script: - pip install isort # Install isort in this job's environment script: - echo "Applying autopep8 formatting to ${LINT_FORMAT_TARGETS}..." - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS} - echo "autopep8 formatting complete." - echo "Current directory $(pwd)" - ls -la - echo "Applying isort to '${FORMAT_TARGETS}' directory..." # isort will use pyproject.toml for configuration if present in the workspace root - | if [ -d "${FORMAT_TARGETS}" ]; then isort "${FORMAT_TARGETS}" echo "isort formatting complete." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping isort." fi artifacts: paths: - noctua/ - . # Pass the modified workspace expire_in: 1 hour apply_isort_format: stage: format_and_lint # Job 4: Apply autopep8 apply_autopep8: stage: setup_and_format tags: - git-run-ia2 needs: - job: apply_autopep8_format - job: apply_isort artifacts: true before_script: - pip install autopep8 # Install autopep8 in this job's environment script: - echo "Applying isort import sorting to ${LINT_FORMAT_TARGETS}..." - isort ${LINT_FORMAT_TARGETS} - echo "isort complete." - echo "Current directory $(pwd)" - ls -la - echo "Applying autopep8 to '${FORMAT_TARGETS}' directory..." - | if [ -d "${FORMAT_TARGETS}" ]; then autopep8 --in-place --recursive --aggressive --aggressive "${FORMAT_TARGETS}" echo "autopep8 formatting complete." else echo "Warning: Directory '${FORMAT_TARGETS}' not found. Skipping autopep8." fi artifacts: paths: - noctua/ - . # Pass the modified workspace (this is the fully formatted code) expire_in: 1 hour run_pylint_check: stage: format_and_lint # Job 5: Run Pylint run_pylint: stage: lint # Separate stage for non-modifying checks tags: - git-run-ia2 needs: - job: apply_isort_format - job: apply_autopep8 # Get the fully formatted code artifacts: true before_script: - pip install pylint # Crucially, also ensure the project itself is "installed" or accessible # for pylint to resolve its internal imports and dependencies. # If the artifact from apply_autopep8 doesn't guarantee a fully functional # python environment with noctua installed, we might need to `pip install -e .` again. # However, since install_noctua did `pip install -e .` and we pass the whole # workspace, the .egg-info or similar should be present, making `noctua` importable. # Let's assume the workspace artifact correctly sets up the Python path for `noctua`. # If pylint has import errors for 'noctua' or its submodules, add `pip install -e .` here. # Test: - echo "Ensuring noctua is importable for pylint..." - python -c "import noctua; print(f'Successfully imported noctua v{noctua.__version__}')" || \ (echo "Failed to import noctua, trying pip install -e ." && pip install -e . && \ python -c "import noctua; print(f'Successfully imported noctua v{noctua.__version__} after re-install')") script: - echo "Running pylint code quality check on '${PYLINT_TARGETS}'..." # .pylintrc should be at the project root, available from artifact # The `pip install -e .` in prepare_and_install ensures pylint can find 'noctua' - pylint --rcfile=.pylintrc ${PYLINT_TARGETS} - echo "Current directory $(pwd)" - ls -la - echo "Running pylint on '${PYLINT_TARGETS}'..." # .pylintrc should be at the project root, available from the artifact - pylint --rcfile=.pylintrc "${PYLINT_TARGETS}" - echo "Pylint check complete." # This job acts as a gate. If it fails, the pipeline stops here (unless allow_failure=true). # No file artifacts are typically produced by pylint itself. rules: # Standard rules to run on MRs and default branch - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual allow_failure: true # Allow manual trigger to not fail overall pipeline if desired # --- Optional: Auto Commit Job (Add if you want CI to commit changes) --- # commit_formatted_code: # stage: auto_commit # tags: # - git-run-ia2 # needs: # - job: run_pylint # Must pass pylint # - job: apply_autopep8 # Needs the final code state from formatting # artifacts: true # before_script: # # Git and SSH setup (ensure SSH_DEPLOY_KEY CI/CD variable is set as File type) # - apt-get update -y && apt-get install -y openssh-client git # - eval $(ssh-agent -s) # - mkdir -p ~/.ssh && chmod 700 ~/.ssh # - echo "$SSH_DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_ci_deploy && chmod 600 ~/.ssh/id_ci_deploy # - ssh-add ~/.ssh/id_ci_deploy # - ssh-keyscan -p ${CI_SERVER_PORT:-22} $CI_SERVER_HOST >> ~/.ssh/known_hosts && chmod 644 ~/.ssh/known_hosts # - git config --global user.email "${GIT_USER_EMAIL}" # - git config --global user.name "${GIT_USER_NAME}" # # Ensure we are on the correct branch and have the latest files from artifacts # - git checkout "$CI_COMMIT_BRANCH" # script: # - echo "Checking for formatting changes to commit..." # - | # # Add only the formatted targets to avoid committing other unintended changes # git add "${FORMAT_TARGETS}" # # if ! git diff --cached --quiet HEAD; then # Check staged changes against HEAD # echo "Code formatting changes applied. Committing to branch '${CI_COMMIT_BRANCH}'." # # Option 1: Commit to a NEW branch (Safer) # # git checkout -B "${FORMATTED_BRANCH_NAME}" # # git commit -m "ci: Apply automated code formatting [skip ci]" # # git push -u origin "${FORMATTED_BRANCH_NAME}" -o ci.skip # # echo "Changes pushed to new branch '${FORMATTED_BRANCH_NAME}'. Please review and merge." # # # Option 2: Commit directly to the CURRENT branch (Use with extreme caution!) # # This is generally NOT recommended for branches that developers also work on directly. # # Only suitable if this CI job is the SOLE writer to this branch for formatting. # git commit -m "ci: Apply automated code formatting [skip ci]" # echo "Pushing formatting changes to '${CI_COMMIT_BRANCH}'..." # git push origin HEAD:"${CI_COMMIT_BRANCH}" -o ci.skip # Push current HEAD to remote branch # echo "Formatting changes pushed to '${CI_COMMIT_BRANCH}'." # else # echo "No formatting changes to commit." # fi # rules: # # Example: Only run manually on the default branch after all checks pass # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "schedule" # Avoid on schedules # when: manual # Make this a conscious decision # allow_failure: false # If it runs, it must succeed