diff --git a/AutoGuard.gitlab-ci.yml b/AutoGuard.gitlab-ci.yml index c20299b..708b550 100644 --- a/AutoGuard.gitlab-ci.yml +++ b/AutoGuard.gitlab-ci.yml @@ -7,33 +7,49 @@ spec: head_ref: type: string default: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME + fail_on_breaking: + type: string + default: "true" + description: "If true, pipeline fails on breaking changes. If false, breaking changes are reported and then passed" --- .autoGuard: - image: "docker" + image: "docker:latest" services: - docker:dind - + variables: + DOCKER_DRIVER: overlay2 + before_script: - docker pull alexx882/auto-oas:1.2 - - docker pull openapitools/openapi-diff:latest + - docker pull djamn/openapi-diff:latest + - apk add --no-cache git script: - - git fetch + - git fetch --all + + - mkdir -p autooas-base + - mkdir -p autooas-head + - chmod -R 777 autooas-base autooas-head - git checkout $[[inputs.base_ref]] - - docker run -v $[[ inputs.source_dir ]]:/project alexx882/auto-oas:1.2 /project /project/autooas-$[[inputs.base_ref]]/oas + - echo "Running Base Analysis..." - - git checkout $[[inputs.head_ref]] - - docker run -v $[[ inputs.source_dir ]]:/project alexx882/auto-oas:1.2 /project /project/autooas-$[[inputs.head_ref]]/oas + - | + if [ -d "$[[ inputs.source_dir ]]" ]; then + docker run -v "$(pwd):/project" alexx882/auto-oas:1.2 "/project/$[[ inputs.source_dir ]]" /project/autooas-base/openapi + else + echo "Directory '$[[ inputs.source_dir ]]' not found in base ref, treating as new project." + fi + - git checkout $[[inputs.head_ref]] + - echo "Running Head Analysis..." + - docker run -v "$(pwd):/project" alexx882/auto-oas:1.2 "/project/$[[ inputs.source_dir ]]" /project/autooas-head/openapi - | - OLD_DIR=autooas-$[[inputs.base_ref]] - NEW_DIR=autooas-$[[inputs.head_ref]] + OLD_DIR=autooas-base + NEW_DIR=autooas-head - set +e - EMPTY_OAS='{ "openapi" : "3.0.1", "info" : { "title" : "", "description" : "Spring Profile: ???", "version" : "" }, "paths" : { }, "components" : { "schemas" : { } }}' - + EMPTY_OAS='{ "openapi": "3.0.1", "info": { "title": "", "version": "" }, "paths": {}, "components": { "schemas": {} } }' echo $EMPTY_OAS > empty.json OLD_FILES=$(find "$OLD_DIR" -type f | sed "s|$OLD_DIR/||" | sort) @@ -46,56 +62,86 @@ spec: OTHER_FILES=$(comm -3 old_files new_files) STATUS=0 - - mkdir oas_diff - - for p in $COMMON_FILES; do - printf "\x20\n\x20\nAnalyzing existing configuration $p\n" - docker run --rm -t \ - -v $(pwd):/specs \ - openapitools/openapi-diff:latest --fail-on-incompatible --html "/specs/oas_diff/$p.html" /specs/$OLD_DIR/$p /specs/$NEW_DIR/$p + + mkdir -p oas_diff + + run_diff() { + local name=$1 + local old_path=$2 + local new_path=$3 + + echo "Diffing $name..." + + set +e + + STATE=$(docker run --rm \ + -v "$(pwd):/specs" \ + openapitools/openapi-diff:latest \ + --state \ + --fail-on-incompatible \ + --html "/specs/oas_diff/$name.html" \ + --markdown "/specs/oas_diff/$name.md" \ + "/specs/$old_path" "/specs/$new_path" 2>/dev/null) + EXIT_CODE=$? - if [ $EXIT_CODE -eq 1 ]; then - echo -e "\e[31mBreaking changes detected in profile $p\033[37m" + + STATE=$(echo "$STATE" | tr -d '\r') + + if [ "$STATE" == "no_changes" ]; then + echo "No changes detected. Removing report files." + rm -f "oas_diff/$name.html" + rm -f "oas_diff/$name.md" + fi + + set -e + + if [ $EXIT_CODE -ne 0 ] || [ "$STATE" == "incompatible" ]; then + echo -e "\e[31mBreaking change detected in $name\e[0m" + return 1 + fi + + if [ "$STATE" == "compatible" ]; then + echo -e "\e[33mCompatible changes detected in $name\e[0m" + return 0 fi - STATUS=$((STATUS + EXIT_CODE)) + + return 0 + } + + if [ -z "$COMMON_FILES" ] && [ -z "$OTHER_FILES" ]; then + echo "ERROR: No OpenAPI files were generated. Analysis failed." + exit 1 + fi + + for p in $COMMON_FILES; do + run_diff "$p" "$OLD_DIR/$p" $NEW_DIR/$p || STATUS=$((STATUS + 1)) done for p in $OTHER_FILES; do if [ -f "$OLD_DIR/$p" ]; then - printf "\x20\n\x20\nAnalyzing deleted configuration $p\n" - docker run --rm -t \ - -v $(pwd):/specs \ - openapitools/openapi-diff:latest --fail-on-incompatible --html "/specs/oas_diff/$p.html" /specs/$OLD_DIR/$p /specs/empty.json - EXIT_CODE=$? - if [ $EXIT_CODE -eq 1 ]; then - echo -e "\e[31mBreaking changes detected in profile $p\033[37m" - fi - STATUS=$((STATUS + EXIT_CODE)) + run_diff "$p" "$OLD_DIR/$p" "empty.json" || STATUS=$((STATUS + 1)) else - printf "\x20\n\x20\nAnalyzing added configuration $p\n" - docker run --rm -t \ - -v $(pwd):/specs \ - openapitools/openapi-diff:latest --fail-on-incompatible --html "/specs/oas_diff/$p.html" /specs/empty.json /specs/$NEW_DIR/$p - EXIT_CODE=$? - if [ $EXIT_CODE -eq 1 ]; then - echo -e "\e[31mBreaking changes detected in profile $p\033[37m" - fi - STATUS=$((STATUS + EXIT_CODE)) + run_diff "$p" "empty.json" "$NEW_DIR/$p" || STATUS=$((STATUS + 1)) fi done - - set -e - if [ $STATUS -gt 0 ]; then - echo -e "\e[31mBreaking changes detected" - exit 1 + if [ $STATUS -gt 0 ]; then + if [ "$[[ inputs.fail_on_breaking ]]" = "true" ]; then + echo "Fail on breaking is ENABLED. Failing job." + exit 1 + else + echo "Fail on breaking is DISABLED. Job passes with warnings." + exit 0 + fi + else + echo -e "\e[32mNo breaking changes found.\e[0m" + exit 0 fi artifacts: when: always name: "OpenAPI specifications" paths: - - "autooas-$[[inputs.base_ref]]/oas*" - - "autooas-$[[inputs.head_ref]]/oas*" - - "oas_diff/*" + - "autooas-base/*.json" + - "autooas-head/*.json" + - "oas_diff/*" \ No newline at end of file