Commit 4dbf021f authored by Davide Ricci's avatar Davide Ricci
Browse files

Update .gitlab-ci.yml file

parent 6c4a30ff
Loading
Loading
Loading
Loading
Loading
+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