image: python:3.12 # Primary docker image to use (you can override this for each job)

stages:
  - install # Define the stages
  - test
  - build
  - release
  - containerize

variables: # Those are global variables that will be inherited by all jobs
  PROJECT_NAME: "cicdiaries" 
  VENV_PATH: .venv 
  IMAGE_TAG: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" 
  RUNNER_GENERATE_ARTIFACTS_METADATA: true
  IMAGE_URI: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA


install_deps:
  stage: install
  cache:
    key: 
      files: ["requirements.txt"]
    paths:
      - $VENV_PATH/
  script:
    - pip install virtualenv
    - virtualenv $VENV_PATH
    - source $VENV_PATH/bin/activate
    - $VENV_PATH/bin/pip install -r requirements.txt


code-audit:
  stage: test
  script:
   - echo "Implement me!" # TODO: run code auditing




test:
  stage: test
  needs: [install_deps] # This means that this job must be executed after the app has been installed
  script:
   - echo "Implement me!" # TODO: run tests for the app


lint:
  stage: test
  needs: [install_deps]
  script:
   - echo "Implement me!" # TODO: lint the code

build_binary: # This is a complete step that builds a binary out of the cicdiaries app.
  stage: build
  cache:
    key: 
      files: ["requirements.txt"]
    paths:
      - $VENV_PATH/
  script: 
    - pip install pyinstaller
    - pip install -r requirements.txt
    - source $VENV_PATH/bin/activate

    - |
      pyinstaller --onefile \
      --add-data "app/website/templates:website/templates" \
      --add-data "app/website/static:website/static" \
      app/wsgi.py
    - tar -czf cicdiaries-binary.tar.gz dist/
  artifacts: # This is a keyword used to tell the pipeline to generate a new artifact
    paths:
      - cicdiaries-binary.tar.gz
    expire_in: 1 week

create_release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  dependencies:
    - build_binary
  script:
    - echo "Creating release..."
  release:
    name: "Release $CI_COMMIT_TAG"
    tag_name: "$CI_COMMIT_TAG"
    description: "Binary build for cicdiaries"
    assets:
      links:
        - name: "Download cicdiaries binary"
          url: "$CI_PROJECT_URL/-/jobs/$CI_JOB_ID/artifacts/file/cicdiaries-binary.zip"
  rules:
    - if: $CI_COMMIT_TAG

build_push_image:
  stage: containerize
  image: docker:latest # Here we set a new image to run the job
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin

  script:
    - docker build -t "$IMAGE_URI" -t "$CI_REGISTRY_IMAGE:latest" .
    - docker push "$IMAGE_URI"
    - docker push "$CI_REGISTRY_IMAGE:latest"

sign_image:
  stage: containerize
  image: docker:latest
  variables:
    COSIGN_YES: "true"
    COSIGN_REGISTRY_REFERRERS_MODE: "legacy"
    COSIGN_EXPERIMENTAL: 1

  before_script:
    - apk add --update cosign jq

    - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin

  script:
    - DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE_URI")
    - cosign generate-key-pair --output-key-prefix cosign
    - |
      cosign sign --key cosign.key  "$DIGEST" \
      --annotations "com.gitlab.ci.user.name=$GITLAB_USER_NAME" \
      --annotations "com.gitlab.ci.pipeline.id=$CI_PIPELINE_ID" \
      --annotations "com.gitlab.ci.pipeline.url=$CI_PIPELINE_URL" \
      --annotations "com.gitlab.ci.job.id=$CI_JOB_ID" \
      --annotations "com.gitlab.ci.job.url=$CI_JOB_URL" \
      --annotations "com.gitlab.ci.commit.sha=$CI_COMMIT_SHA" \
      --annotations "com.gitlab.ci.commit.ref.name=$CI_COMMIT_REF_NAME" \
      --annotations "com.gitlab.ci.project.path=$CI_PROJECT_PATH" \
      --annotations "org.opencontainers.image.source=$CI_PROJECT_URL" \
      --annotations "org.opencontainers.image.revision=$CI_COMMIT_SHA" \
      --annotations "tag=$IMAGE_TAG"
    - cosign verify --key cosign.pub --annotations "tag=$IMAGE_TAG" "$DIGEST" | jq .





