From 399d956101c46e487fe83ce624107f6a91c3b867 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sun, 24 May 2026 23:07:40 +0300 Subject: [PATCH 1/3] feat: consume JSON output, add cli-version input - Action now uses dm config --format json instead of awk/sed text parsing - Add cli-version input to pin CLI version for reproducible results - README recommends @v1 instead of @main - Add Reproducibility section to README --- README.md | 16 ++++++++++++++-- action.yml | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c6a0616..8ffa35b 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: devops-maturity/devops-maturity-action@main + - uses: devops-maturity/devops-maturity-action@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} ``` @@ -79,6 +79,7 @@ D202: false # Functional Testing (must have) | `commit-message` | no | `chore: update devops-maturity badges` | Commit message for the badge update. | | `pr-title` | no | `chore: update devops-maturity badges` | Title of the pull request. | | `pr-body` | no | *(auto-generated)* | Body text of the pull request. | +| `cli-version` | no | *(latest)* | Pin a specific CLI version for reproducible results (e.g. `0.1.0`). | ## Outputs @@ -95,7 +96,7 @@ D202: false # Functional Testing (must have) ```yaml - id: maturity - uses: devops-maturity/devops-maturity-action@main + uses: devops-maturity/devops-maturity-action@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -123,6 +124,17 @@ shields.io badge using a regular expression. If one is found it is replaced in-place; if none exists the new badge is prepended before the first Markdown heading (or at the very top of the file). +## Reproducibility + +For reproducible CI results, pin both the action and the CLI to specific versions: + +```yaml +- uses: devops-maturity/devops-maturity-action@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + cli-version: '0.1.0' # pin CLI version +``` + ## License [Apache 2.0](LICENSE) \ No newline at end of file diff --git a/action.yml b/action.yml index dbc28b9..7a24858 100644 --- a/action.yml +++ b/action.yml @@ -54,6 +54,13 @@ inputs: [devops-maturity-action](https://github.com/devops-maturity/devops-maturity-action) based on changes to `devops-maturity.yml`. + cli-version: + description: > + Version of the devops-maturity CLI to install (e.g. '0.1.0'). + Defaults to latest. Pinning a specific version ensures reproducible results. + required: false + default: '' + outputs: score: description: 'Overall DevOps maturity score as a percentage (e.g. "72.3%").' @@ -90,27 +97,36 @@ runs: - name: Install devops-maturity CLI shell: bash - run: pip install --quiet devops-maturity + run: | + if [ -n "${{ inputs.cli-version }}" ]; then + pip install --quiet "devops-maturity==${{ inputs.cli-version }}" + else + pip install --quiet devops-maturity + fi - # ── 2. Run the assessment ───────────────────────────────────────────────── + # ── 2. Run the assessment (JSON output, no text parsing) ───────────────── - name: Run devops-maturity assessment id: assessment shell: bash run: | - OUTPUT=$(dm config --file "${{ inputs.file }}" 2>&1) - echo "$OUTPUT" - - SCORE=$(echo "$OUTPUT" | awk '/Your score: / {print $NF}') - LEVEL=$(echo "$OUTPUT" | awk '/Your maturity level: / {print $NF}') - BADGE_URL=$(echo "$OUTPUT" | awk '/Badge URL: / {print $NF}') - # Prefer the CLI-provided Markdown badge; fall back to constructing it - BADGE_MD=$(echo "$OUTPUT" | sed -n 's/^Markdown badge: //p') - if [ -z "$BADGE_MD" ] && [ -n "$BADGE_URL" ]; then - BADGE_MD="[![DevOps Maturity](${BADGE_URL})](https://devops-maturity.github.io/)" + JSON_OUTPUT=$(dm config --file "${{ inputs.file }}" --format json 2>&1) + echo "$JSON_OUTPUT" + + # Validate that we got valid JSON + if ! echo "$JSON_OUTPUT" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then + echo "ERROR: could not parse assessment output as JSON" + echo "Raw output was:" + echo "$JSON_OUTPUT" + exit 1 fi + SCORE=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['score'])") + LEVEL=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['level'])") + BADGE_URL=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_url'])") + BADGE_MD=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_markdown'])") + if [ -z "$LEVEL" ] || [ -z "$BADGE_URL" ]; then - echo "ERROR: could not parse assessment output" + echo "ERROR: missing required fields in JSON output" exit 1 fi From 571307ab69ba19078d9224904ee967c4f1e37303 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sun, 24 May 2026 23:40:25 +0300 Subject: [PATCH 2/3] fix: add text-parsing fallback for CLI without --format json The --format json flag is not yet in the published CLI. Until the CLI release, the action tries JSON first and falls back to awk/sed text parsing for older CLI versions. --- action.yml | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/action.yml b/action.yml index 7a24858..f42bd2c 100644 --- a/action.yml +++ b/action.yml @@ -104,27 +104,35 @@ runs: pip install --quiet devops-maturity fi - # ── 2. Run the assessment (JSON output, no text parsing) ───────────────── + # ── 2. Run the assessment ───────────────────────────────────────────────── + # Tries --format json first (available in CLI >= next release). + # Falls back to text parsing for older CLI versions. - name: Run devops-maturity assessment id: assessment shell: bash run: | - JSON_OUTPUT=$(dm config --file "${{ inputs.file }}" --format json 2>&1) - echo "$JSON_OUTPUT" - - # Validate that we got valid JSON - if ! echo "$JSON_OUTPUT" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then - echo "ERROR: could not parse assessment output as JSON" - echo "Raw output was:" - echo "$JSON_OUTPUT" - exit 1 + OUTPUT=$(dm config --file "${{ inputs.file }}" --format json 2>&1) || true + echo "$OUTPUT" + + # Try JSON path first + if echo "$OUTPUT" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then + echo "→ Parsed as JSON" + SCORE=$(echo "$OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['score'])") + LEVEL=$(echo "$OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['level'])") + BADGE_URL=$(echo "$OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_url'])") + BADGE_MD=$(echo "$OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_markdown'])") + else + # Fallback: text parsing for older CLI (pre --format json) + echo "→ JSON not available, falling back to text parsing" + SCORE=$(echo "$OUTPUT" | awk '/Your score: / {print $NF}') + LEVEL=$(echo "$OUTPUT" | awk '/Your maturity level: / {print $NF}') + BADGE_URL=$(echo "$OUTPUT" | awk '/Badge URL: / {print $NF}') + BADGE_MD=$(echo "$OUTPUT" | sed -n 's/^Markdown badge: //p') + if [ -z "$BADGE_MD" ] && [ -n "$BADGE_URL" ]; then + BADGE_MD="[![DevOps Maturity](${BADGE_URL})](https://devops-maturity.github.io/)" + fi fi - SCORE=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['score'])") - LEVEL=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['level'])") - BADGE_URL=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_url'])") - BADGE_MD=$(echo "$JSON_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['badge_markdown'])") - if [ -z "$LEVEL" ] || [ -z "$BADGE_URL" ]; then echo "ERROR: missing required fields in JSON output" exit 1 From 6de2a70fd2d29fb38463b4be30f006d2ff58dce7 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sun, 24 May 2026 23:48:54 +0300 Subject: [PATCH 3/3] fix: shorten description to under 125 characters --- action.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/action.yml b/action.yml index f42bd2c..a4fdda0 100644 --- a/action.yml +++ b/action.yml @@ -1,7 +1,5 @@ name: 'DevOps Maturity Action' -description: > - Automatically runs the devops-maturity CLI against a devops-maturity.yml file, - updates the README badge, and opens a pull request for review. +description: 'Run devops-maturity CLI, update README badge, and open a PR for review.' author: 'devops-maturity' branding: