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..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: @@ -54,6 +52,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 +95,44 @@ 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 ───────────────────────────────────────────────── + # 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: | - OUTPUT=$(dm config --file "${{ inputs.file }}" 2>&1) + OUTPUT=$(dm config --file "${{ inputs.file }}" --format json 2>&1) || true 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/)" + # 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 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