diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a8d600e..8250b77 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -276,3 +276,29 @@ jobs: echo "Expected '1 changes: 1 error, 0 warning, 0 info', instead got '$output'" >&2 exit 1 fi + oasdiff_breaking_flatten_allof: + runs-on: ubuntu-latest + name: Test breaking action with flatten-allof option + env: + OASDIFF_ACTION_TEST_EXPECTED_OUTPUT: "1 changes: 1 error, 0 warning, 0 info" + steps: + - name: checkout + uses: actions/checkout@v4 + - name: Running breaking action with flatten-allof option + id: test_breaking_flatten_allof + uses: ./breaking + with: + base: 'specs/base-allof.yaml' + revision: 'specs/revision-allof.yaml' + flatten-allof: true + - name: Test breaking action output + run: | + delimiter=$(cat /proc/sys/kernel/random/uuid | tr -d '-') + output=$(cat <<-$delimiter + ${{ steps.test_breaking_flatten_allof.outputs.breaking }} + $delimiter + ) + if [ "$output" != "$OASDIFF_ACTION_TEST_EXPECTED_OUTPUT" ]; then + echo "Expected output '$OASDIFF_ACTION_TEST_EXPECTED_OUTPUT' but got '$output'" >&2 + exit 1 + fi diff --git a/README.md b/README.md index af5bf03..6123792 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ jobs: | `exclude-elements` | `''` | Exclude certain kinds of changes from the output | `endpoints`, `request`, `response` (comma-separated) | | `filter-extension` | `''` | Exclude paths and operations with an OpenAPI Extension matching this expression | regex | | `composed` | `false` | Run in composed mode | `true`, `false` | +| `flatten-allof` | `false` | Merge allOf subschemas into a single schema before diff | `true`, `false` | | `output-to-file` | `''` | Write output to this file path instead of stdout | file path | ### Generate a changelog @@ -60,6 +61,7 @@ jobs: | `exclude-elements` | `''` | Exclude certain kinds of changes from the output | `endpoints`, `request`, `response` (comma-separated) | | `filter-extension` | `''` | Exclude paths and operations with an OpenAPI Extension matching this expression | regex | | `composed` | `false` | Run in composed mode | `true`, `false` | +| `flatten-allof` | `false` | Merge allOf subschemas into a single schema before diff | `true`, `false` | | `prefix-base` | `''` | Prefix to add to all paths in the base spec | string | | `prefix-revision` | `''` | Prefix to add to all paths in the revised spec | string | | `case-insensitive-headers` | `false` | Compare headers case-insensitively | `true`, `false` | @@ -91,6 +93,7 @@ jobs: | `exclude-elements` | `''` | Exclude certain kinds of changes from the output | `endpoints`, `request`, `response` (comma-separated) | | `filter-extension` | `''` | Exclude paths and operations with an OpenAPI Extension matching this expression | regex | | `composed` | `false` | Run in composed mode | `true`, `false` | +| `flatten-allof` | `false` | Merge allOf subschemas into a single schema before diff | `true`, `false` | | `output-to-file` | `''` | Write output to this file path instead of stdout | file path | --- diff --git a/breaking/action.yml b/breaking/action.yml index 9cdc217..7db6239 100644 --- a/breaking/action.yml +++ b/breaking/action.yml @@ -36,6 +36,10 @@ inputs: description: 'Run in composed mode' required: false default: 'false' + flatten-allof: + description: 'Merge allOf subschemas into a single schema before diff' + required: false + default: 'false' output-to-file: description: 'Output to a file at the given path' required: false @@ -57,4 +61,5 @@ runs: - ${{ inputs.exclude-elements }} - ${{ inputs.filter-extension }} - ${{ inputs.composed }} + - ${{ inputs.flatten-allof }} - ${{ inputs.output-to-file }} diff --git a/breaking/entrypoint.sh b/breaking/entrypoint.sh index f217e6d..4d10f95 100755 --- a/breaking/entrypoint.sh +++ b/breaking/entrypoint.sh @@ -16,7 +16,8 @@ readonly deprecation_days_stable="$7" readonly exclude_elements="$8" readonly filter_extension="$9" readonly composed="${10}" -readonly output_to_file="${11}" +readonly flatten_allof="${11}" +readonly output_to_file="${12}" write_output () { _write_output_output="$1" @@ -38,7 +39,7 @@ write_output () { echo "$_write_output_output" >>"$GITHUB_OUTPUT" } -echo "running oasdiff breaking... base: $base, revision: $revision, fail_on: $fail_on, include_checks: $include_checks, include_path_params: $include_path_params, deprecation_days_beta: $deprecation_days_beta, deprecation_days_stable: $deprecation_days_stable, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, output_to_file: $output_to_file" +echo "running oasdiff breaking... base: $base, revision: $revision, fail_on: $fail_on, include_checks: $include_checks, include_path_params: $include_path_params, deprecation_days_beta: $deprecation_days_beta, deprecation_days_stable: $deprecation_days_stable, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, flatten_allof: $flatten_allof, output_to_file: $output_to_file" # Build flags to pass in command flags="" @@ -63,6 +64,9 @@ fi if [ "$composed" = "true" ]; then flags="$flags -c" fi +if [ "$flatten_allof" = "true" ]; then + flags="$flags --flatten-allof" +fi echo "flags: $flags" # Check for breaking changes diff --git a/changelog/action.yml b/changelog/action.yml index 30c016c..691db26 100644 --- a/changelog/action.yml +++ b/changelog/action.yml @@ -23,6 +23,10 @@ inputs: description: 'Run in composed mode' required: false default: 'false' + flatten-allof: + description: 'Merge allOf subschemas into a single schema before diff' + required: false + default: 'false' output-to-file: description: 'Output to a file at the given path' required: false @@ -64,6 +68,7 @@ runs: - ${{ inputs.exclude-elements }} - ${{ inputs.filter-extension }} - ${{ inputs.composed }} + - ${{ inputs.flatten-allof }} - ${{ inputs.output-to-file }} - ${{ inputs.prefix-base }} - ${{ inputs.prefix-revision }} diff --git a/changelog/entrypoint.sh b/changelog/entrypoint.sh index 914640a..fdc1cf5 100755 --- a/changelog/entrypoint.sh +++ b/changelog/entrypoint.sh @@ -31,15 +31,16 @@ readonly include_path_params="$3" readonly exclude_elements="$4" readonly filter_extension="$5" readonly composed="$6" -readonly output_to_file="$7" -readonly prefix_base="$8" -readonly prefix_revision="$9" -readonly case_insensitive_headers="${10}" -readonly format="${11}" -readonly template="${12}" -readonly level="${13}" +readonly flatten_allof="$7" +readonly output_to_file="$8" +readonly prefix_base="$9" +readonly prefix_revision="${10}" +readonly case_insensitive_headers="${11}" +readonly format="${12}" +readonly template="${13}" +readonly level="${14}" -echo "running oasdiff changelog base: $base, revision: $revision, include_path_params: $include_path_params, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, output_to_file: $output_to_file, prefix_base: $prefix_base, prefix_revision: $prefix_revision, case_insensitive_headers: $case_insensitive_headers, format: $format, template: $template, level: $level" +echo "running oasdiff changelog base: $base, revision: $revision, include_path_params: $include_path_params, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, flatten_allof: $flatten_allof, output_to_file: $output_to_file, prefix_base: $prefix_base, prefix_revision: $prefix_revision, case_insensitive_headers: $case_insensitive_headers, format: $format, template: $template, level: $level" # Build flags to pass in command flags="" @@ -55,6 +56,9 @@ fi if [ "$composed" = "true" ]; then flags="$flags -c" fi +if [ "$flatten_allof" = "true" ]; then + flags="$flags --flatten-allof" +fi if [ -n "$prefix_base" ]; then flags="$flags --prefix-base $prefix_base" fi diff --git a/diff/action.yml b/diff/action.yml index 1aa1904..847b152 100644 --- a/diff/action.yml +++ b/diff/action.yml @@ -31,6 +31,10 @@ inputs: description: 'Run in composed mode' required: false default: 'false' + flatten-allof: + description: 'Merge allOf subschemas into a single schema before diff' + required: false + default: 'false' output-to-file: description: 'Output to a file at the given path' required: false @@ -50,4 +54,5 @@ runs: - ${{ inputs.exclude-elements }} - ${{ inputs.filter-extension }} - ${{ inputs.composed }} + - ${{ inputs.flatten-allof }} - ${{ inputs.output-to-file }} diff --git a/diff/entrypoint.sh b/diff/entrypoint.sh index 8841523..c77c78c 100755 --- a/diff/entrypoint.sh +++ b/diff/entrypoint.sh @@ -33,9 +33,10 @@ readonly include_path_params="$5" readonly exclude_elements="$6" readonly filter_extension="$7" readonly composed="$8" -readonly output_to_file="$9" +readonly flatten_allof="$9" +readonly output_to_file="${10}" -echo "running oasdiff diff base: $base, revision: $revision, format: $format, fail_on_diff: $fail_on_diff, include_path_params: $include_path_params, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, output_to_file: $output_to_file" +echo "running oasdiff diff base: $base, revision: $revision, format: $format, fail_on_diff: $fail_on_diff, include_path_params: $include_path_params, exclude_elements: $exclude_elements, filter_extension: $filter_extension, composed: $composed, flatten_allof: $flatten_allof, output_to_file: $output_to_file" # Build flags to pass in command flags="" @@ -57,6 +58,9 @@ fi if [ "$composed" = "true" ]; then flags="$flags -c" fi +if [ "$flatten_allof" = "true" ]; then + flags="$flags --flatten-allof" +fi echo "flags: $flags" # *** github action step output *** diff --git a/specs/base-allof.yaml b/specs/base-allof.yaml new file mode 100644 index 0000000..6ff4caf --- /dev/null +++ b/specs/base-allof.yaml @@ -0,0 +1,47 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Petstore allOf +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + parameters: + - name: petId + in: path + required: true + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" +components: + schemas: + BaseEntity: + type: object + required: + - id + properties: + id: + type: integer + format: int64 + PetFields: + type: object + required: + - name + properties: + name: + type: string + tag: + type: string + Pet: + allOf: + - $ref: "#/components/schemas/BaseEntity" + - $ref: "#/components/schemas/PetFields" diff --git a/specs/revision-allof.yaml b/specs/revision-allof.yaml new file mode 100644 index 0000000..36d1386 --- /dev/null +++ b/specs/revision-allof.yaml @@ -0,0 +1,45 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Petstore allOf +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + parameters: + - name: petId + in: path + required: true + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" +components: + schemas: + BaseEntity: + type: object + required: + - id + properties: + id: + type: integer + format: int64 + PetFields: + type: object + properties: + name: + type: string + tag: + type: string + Pet: + allOf: + - $ref: "#/components/schemas/BaseEntity" + - $ref: "#/components/schemas/PetFields"