Commit 58cd1b90 authored by vertighel's avatar vertighel
Browse files

Pipeline test

parent b100874c
Loading
Loading
Loading
Loading
Loading
+143 −61
Original line number Diff line number Diff line
image: python:3.12 # Use the Python version matching your requires-python
# software-di-controllo/.gitlab-ci.yml

image: python:3.12

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  # Define targets for linters and formatters
  # For a package 'noctua' and a 'tests' directory at the root:
  LINT_FORMAT_TARGETS: "noctua tests"
  PYLINT_TARGETS: "noctua" # Usually just the package itself
  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" # Cache per branch
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - .cache/pip
    - venv/ # If you choose to use a virtual environment within the CI job
    # If you decide to use a venv within jobs, cache it here too
    # - venv/

stages:
  - setup # Combined installation of tools and project
  - setup_project # Just installs the project itself for context
  - lint_and_format
  # - test # Placeholder for future tests
  # - build # Placeholder
  # - deploy # Placeholder
  - auto_commit_changes # New stage for committing
  # - test
  # - build
  # - deploy

# Job to install linters, formatters, and the project itself
prepare_environment:
  stage: setup
# Job to install the project itself (so linters understand its structure)
install_project_context:
  stage: setup_project
  tags:
    - git-run-ia2 # Your specific runner tag
    - git-run-ia2
  script:
    - echo "Python version:"
    - python -V
    - echo "Pip version:"
    - pip -V
    - pip install --upgrade pip
    # Install linters, formatters, and any build tools
    - pip install isort autopep8 pylint black # Added black as an option
    # Install the project in editable mode and its dependencies
    # This ensures linters understand your package structure and imports
    - echo "Installing project 'noctua' and its dependencies..."
    - pip install -e .
    - echo "Setup complete."
  artifacts:
    paths:
      - . # Pass the whole workspace if subsequent jobs depend on full checkout + venv
      # More fine-grained would be to only pass venv if used, and have other jobs checkout code
    expire_in: 1 hour # Keep artifacts for a limited time
    - 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)

# Job for isort (check and apply/diff)
isort_check_and_format:
isort_check: # Renamed to just check, formatting applied locally is preferred
  stage: lint_and_format
  tags:
    - git-run-ia2
  needs: # GitLab 12.2+ feature for DAG pipelines; use 'dependencies' for older GitLab
    - job: prepare_environment
      artifacts: true # Inherit artifacts
  # 'needs' or 'dependencies' not strictly needed if this job checks out code and installs tools
  before_script:
    - pip install isort
  script:
    - echo "Running isort..."
    # Option 1: Check only (fails pipeline if changes are needed)
    - echo "Checking import order with isort..."
    - isort --check-only --diff ${LINT_FORMAT_TARGETS}
    # Option 2: Apply formatting (uncomment if you want CI to fix and commit, more complex)
    # - isort ${LINT_FORMAT_TARGETS}
    # - |
    #   # Check if isort made changes
    #   git diff --quiet || \
    #     (echo "isort made changes. Consider committing them." && exit 1) # Or auto-commit
    - echo "isort check complete."
  rules:
    - 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 pipeline
      allow_failure: true

# Job for autopep8 (or black)
style_format_code:
style_check_code: # Renamed to just check
  stage: lint_and_format
  tags:
    - git-run-ia2
  needs:
    - job: prepare_environment
      artifacts: true
  before_script:
    - pip install autopep8 # Or black if you switch
  script:
    - echo "Running autopep8 to format Python code..."
    # Option 1: Check only (using --diff and exiting if changes needed)
    - echo "Checking code style with autopep8..."
    - autopep8 --diff --recursive ${LINT_FORMAT_TARGETS} > autopep8.diff || true # Capture diff, don't fail yet
    - autopep8 --diff --recursive ${LINT_FORMAT_TARGETS} > autopep8.diff || true
    - |
      if [ -s autopep8.diff ]; then
        echo "autopep8 found style issues. Diff:"
        echo "autopep8 found style issues that would be applied. Diff:"
        cat autopep8.diff
        # To make it a check that fails, exit 1.
        # For just reporting, don't exit 1.
        # exit 1 # Uncomment to fail the job if diff is not empty
        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
    # Option 2: Apply formatting (uncomment if CI should fix, more complex)
    # - autopep8 --in-place --recursive --aggressive --aggressive ${LINT_FORMAT_TARGETS}
    # - |
    #   git diff --quiet || \
    #     (echo "autopep8 made changes. Consider committing them." && exit 1)
    - echo "autopep8 check complete."
  artifacts:
    when: always # Capture diff even on failure
    when: on_failure # Capture diff only if the check "fails" (if you uncomment exit 1) or always
    paths:
      - autopep8.diff
  rules:
@@ -108,3 +85,108 @@ style_format_code:
    - 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
  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
    - git checkout "$CI_COMMIT_BRANCH"
    - git pull origin "$CI_COMMIT_BRANCH" # Ensure we have the latest
  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..."
    - find ${LINT_FORMAT_TARGETS} -type f -name "*.py" -exec sed -i 's/[[:space:]]*$//' {} \;
    - |
      # 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
        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}'."
      else
        echo "No formatting changes to commit."
      fi