diff --git a/.github/actions/utils/check-permissions/action.yml b/.github/actions/utils/check-permissions/action.yml new file mode 100644 index 0000000..a9ab002 --- /dev/null +++ b/.github/actions/utils/check-permissions/action.yml @@ -0,0 +1,82 @@ +name: Verify users rights +description: "Fails the workflow run if the triggering user lacks write permission or is not in the given organisation team." + +inputs: + message: + description: "Message that will be shown as comment in case of access denial" + default: "⚠️ You don’t have permission to run this workflow. Please ask a maintainer to trigger it for you." + team: + description: "Name of the team that contains trusted contributors" + default: "contributors" + +runs: + using: composite + steps: + - name: Check repository permission / team membership + uses: actions/github-script@v8 + env: + TEAM: ${{ inputs.team }} + MESSAGE: ${{ inputs.message }} + with: + script: | + const {owner, repo} = context.repo; + // Get actor from event payload first, fallback to GITHUB_ACTOR + const actor = context.payload.actor || + context.actor || + process.env.GITHUB_ACTOR; + const team = process.env.TEAM + const denialMessage = process.env.MESSAGE + + //------------------------------------------------------------------ + // 1) Check collaborator permission (works for user *and* org repos) + //------------------------------------------------------------------ + const perm = (await github.rest.repos.getCollaboratorPermissionLevel({ + owner, repo, username: actor + })).data.permission; // admin | maintain | write | triage | read | none + + if (['admin', 'maintain', 'write'].includes(perm)) { + core.info(`${actor} has ${perm} permission → authorised ✅`); + return; + } + + //------------------------------------------------------------------ + // 2) Repo is under an organisation? Then allow specific team members + //------------------------------------------------------------------ + if (context.payload.repository.owner.type === 'Organization') { + try { + await github.rest.teams.getMembershipForUserInOrg({ + org: owner, + team_slug: team, + username: actor + }); + core.info(`${actor} is in org team “${team}” → authorised ✅`); + return; + } catch (_) { + core.info(`${actor} is not in team “${team}”.`); + } + } + + let orgMember = true; + try { + await github.rest.orgs.getMembershipForUser({org: owner, username: actor}); + core.info(`${actor} is in org” → authorised ✅`); + return; + } catch (_) { + core.info(`${actor} is not in org “${owner}”.`); + } + + //------------------------------------------------------------------ + // 3) Post PR comment if applicable, then fail + //------------------------------------------------------------------ + if (context.payload.pull_request || context.payload.issue?.pull_request) { + const issueNumber = (context.payload.pull_request?.number) + ?? (context.payload.issue.number); + await github.rest.issues.createComment({ + owner, repo, + issue_number: issueNumber, + body: denialMessage + }); + core.info(`Refusal comment posted to PR #${issueNumber}`); + } + + core.setFailed(`${actor} is not authorised ❌`); diff --git a/.github/actions/utils/determine-ref/action.yml b/.github/actions/utils/determine-ref/action.yml new file mode 100644 index 0000000..786641b --- /dev/null +++ b/.github/actions/utils/determine-ref/action.yml @@ -0,0 +1,55 @@ +name: "Determine checkout ref" +description: "Determines the correct ref to checkout based on event context" + +outputs: + ref: + description: "The ref to checkout" + value: ${{ steps.determine.outputs.ref }} + sha: + description: "The SHA to checkout" + value: ${{ steps.determine.outputs.sha }} + +runs: + using: "composite" + steps: + - name: Determine ref and SHA + id: determine + uses: actions/github-script@v8 + with: + script: | + const {owner, repo} = context.repo; + let ref, sha; + + if (context.eventName === 'pull_request') { + // For PR events, use merge ref to test the merged state + const prNumber = context.payload.pull_request.number; + ref = `refs/pull/${prNumber}/merge`; + sha = context.payload.pull_request.head.sha; + core.info(`PR event detected: Using merge ref for PR #${prNumber}`); + core.info(`Head SHA: ${sha}`); + } else if (context.eventName === 'issue_comment' && context.payload.issue?.pull_request) { + // For PR comments, fetch the PR to get head SHA + const prNumber = context.payload.issue.number; + ref = `refs/pull/${prNumber}/merge`; + + const pr = await github.rest.pulls.get({ + owner, + repo, + pull_number: prNumber + }); + sha = pr.data.head.sha; + + core.info(`PR comment detected: Using merge ref for PR #${prNumber}`); + core.info(`Head SHA: ${sha}`); + } else { + // For workflow_dispatch and other events, use the current branch + ref = context.ref; + sha = context.sha; + core.info(`Standard event: Using current ref ${ref}`); + core.info(`SHA: ${sha}`); + } + + core.setOutput('ref', ref); + core.setOutput('sha', sha); + core.exportVariable('REF', ref); + core.exportVariable('SHA', sha); \ No newline at end of file diff --git a/.github/actions/utils/should-run/action.yml b/.github/actions/utils/should-run/action.yml new file mode 100644 index 0000000..e96bafc --- /dev/null +++ b/.github/actions/utils/should-run/action.yml @@ -0,0 +1,38 @@ +name: "Should Run" +description: "Determines whether the workflow should proceed based on event context" + +outputs: + shouldRun: + description: "Flag if tests were triggered via comment or UI which leads to running the following jobs" + value: ${{ steps.should_run.outputs.shouldRun }} + +runs: + using: "composite" + steps: + - name: Should Run + id: should_run + uses: actions/github-script@v8 + with: + script: | + const ev = context.eventName; + const body = context.payload?.comment?.body ?? ''; + let shouldRun = false; + + if (ev === 'workflow_dispatch') { + shouldRun = true; + } else if (ev === 'pull_request') { + // Auto-run smoke tests on PR workflow changes + shouldRun = true; + } else if (ev === 'issue_comment' && context.payload?.issue?.pull_request) { + // For issue comments on PRs, check if PR is closed first + const issueState = context.payload?.issue?.state; + if (issueState === 'closed') { + core.info(`PR #${context.payload.issue.number} is closed, skipping execution`); + shouldRun = false; + } else { + shouldRun = /^\s*\/gha\s+run\b/i.test(body || ''); + } + } + + core.setOutput('shouldRun', String(shouldRun)); + core.info(`Parsed shouldRun: ${shouldRun}`); \ No newline at end of file diff --git a/.github/tests/events/check-permissions/permissions_authorized.json b/.github/tests/events/check-permissions/permissions_authorized.json new file mode 100644 index 0000000..642343e --- /dev/null +++ b/.github/tests/events/check-permissions/permissions_authorized.json @@ -0,0 +1,24 @@ +{ + "event_name": "pull_request", + "action": "opened", + "actor": "frawless", + "pull_request": { + "number": 123, + "title": "Test authorized user", + "head": { + "ref": "test-branch", + "sha": "abc123456789", + "repo": { + "name": "ci-playground", + "owner": { "login": "frawless" } + } + } + }, + "repository": { + "name": "ci-playground", + "owner": { + "login": "frawless", + "type": "User" + } + } +} diff --git a/.github/tests/events/check-permissions/permissions_unauthorized.json b/.github/tests/events/check-permissions/permissions_unauthorized.json new file mode 100644 index 0000000..7df2997 --- /dev/null +++ b/.github/tests/events/check-permissions/permissions_unauthorized.json @@ -0,0 +1,24 @@ +{ + "event_name": "pull_request", + "action": "opened", + "actor": "pepa", + "pull_request": { + "number": 66666666666, + "title": "Test unauthorized user", + "head": { + "ref": "test-branch", + "sha": "def987654321", + "repo": { + "name": "ci-playground", + "owner": { "login": "pepa" } + } + } + }, + "repository": { + "name": "ci-playground", + "owner": { + "login": "frawless", + "type": "User" + } + } +} diff --git a/.github/tests/events/should-run/dispatch_default.json b/.github/tests/events/should-run/dispatch_default.json new file mode 100644 index 0000000..a7a386f --- /dev/null +++ b/.github/tests/events/should-run/dispatch_default.json @@ -0,0 +1,13 @@ +{ + "action": "workflow_dispatch", + "event_name": "workflow_dispatch", + "inputs": {}, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + }, + "ref": "refs/heads/main", + "head_commit": { + "id": "3333333333333333333333333333333333333333" + } +} diff --git a/.github/tests/events/should-run/issue_comment_closed_issue.json b/.github/tests/events/should-run/issue_comment_closed_issue.json new file mode 100644 index 0000000..fcaf04e --- /dev/null +++ b/.github/tests/events/should-run/issue_comment_closed_issue.json @@ -0,0 +1,15 @@ +{ + "event_name": "issue_comment", + "action": "created", + "comment": { + "body": "/gha run profile=operators,operands" + }, + "issue": { + "number": 123, + "state": "closed" + }, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + } +} diff --git a/.github/tests/events/should-run/issue_comment_closed_pr.json b/.github/tests/events/should-run/issue_comment_closed_pr.json new file mode 100644 index 0000000..30c77cf --- /dev/null +++ b/.github/tests/events/should-run/issue_comment_closed_pr.json @@ -0,0 +1,25 @@ +{ + "event_name": "issue_comment", + "action": "created", + "comment": { + "body": "/gha run pipeline=regression,upgrade" + }, + "issue": { + "number": 42, + "state": "closed", + "pull_request": { + "head": { + "ref": "feature-123", + "sha": "1111111111111111111111111111111111111111", + "repo": { + "name": "test-repo", + "owner": { "login": "batman" } + } + } + } + }, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + } +} diff --git a/.github/tests/events/should-run/issue_comment_no_trigger.json b/.github/tests/events/should-run/issue_comment_no_trigger.json new file mode 100644 index 0000000..60b6028 --- /dev/null +++ b/.github/tests/events/should-run/issue_comment_no_trigger.json @@ -0,0 +1,24 @@ +{ + "event_name": "issue_comment", + "action": "created", + "comment": { + "body": "This comment does not contain the trigger phrase" + }, + "issue": { + "number": 42, + "pull_request": { + "head": { + "ref": "feature-123", + "sha": "1111111111111111111111111111111111111111", + "repo": { + "name": "test-repo", + "owner": { "login": "batman" } + } + } + } + }, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + } +} diff --git a/.github/tests/events/should-run/issue_comment_trigger.json b/.github/tests/events/should-run/issue_comment_trigger.json new file mode 100644 index 0000000..d7f5fa8 --- /dev/null +++ b/.github/tests/events/should-run/issue_comment_trigger.json @@ -0,0 +1,24 @@ +{ + "event_name": "issue_comment", + "action": "created", + "comment": { + "body": "/gha run" + }, + "issue": { + "number": 42, + "pull_request": { + "head": { + "ref": "feature-123", + "sha": "1111111111111111111111111111111111111111", + "repo": { + "name": "test-repo", + "owner": { "login": "batman" } + } + } + } + }, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + } +} diff --git a/.github/tests/events/should-run/pull_request.json b/.github/tests/events/should-run/pull_request.json new file mode 100644 index 0000000..b7787f4 --- /dev/null +++ b/.github/tests/events/should-run/pull_request.json @@ -0,0 +1,20 @@ +{ + "event_name": "pull_request", + "action": "opened", + "pull_request": { + "number": 42, + "title": "Test PR", + "head": { + "ref": "feature-123", + "sha": "1111111111111111111111111111111111111111", + "repo": { + "name": "test-repo", + "owner": { "login": "batman" } + } + } + }, + "repository": { + "name": "test-repo", + "owner": { "login": "batman" } + } +} diff --git a/.github/tests/scenarios/check-permissions.yaml b/.github/tests/scenarios/check-permissions.yaml new file mode 100644 index 0000000..1de8b92 --- /dev/null +++ b/.github/tests/scenarios/check-permissions.yaml @@ -0,0 +1,14 @@ +scenarios: + - id: authorized-user + description: "Real authorized user (repository owner/collaborator)" + event: pull_request + fixture: .github/tests/events/check-permissions/permissions_authorized.json + expectations: + should_pass: "true" + + - id: unauthorized-user + description: "Real unauthorized user (external contributor)" + event: pull_request + fixture: .github/tests/events/check-permissions/permissions_unauthorized.json + expectations: + should_pass: "false" diff --git a/.github/tests/scenarios/should-run.yaml b/.github/tests/scenarios/should-run.yaml new file mode 100644 index 0000000..f8ecb2c --- /dev/null +++ b/.github/tests/scenarios/should-run.yaml @@ -0,0 +1,42 @@ +scenarios: + - id: workflow-dispatch + description: "Workflow dispatch should always run" + event: workflow_dispatch + fixture: .github/tests/events/should-run/dispatch_default.json + expectations: + should_run: "true" + + - id: pull-request + description: "Pull request should always run" + event: pull_request + fixture: .github/tests/events/should-run/pull_request.json + expectations: + should_run: "true" + + - id: issue-comment-trigger + description: "Issue comment with /gha run trigger should run" + event: issue_comment + fixture: .github/tests/events/should-run/issue_comment_trigger.json + expectations: + should_run: "true" + + - id: issue-comment-no-trigger + description: "Issue comment without trigger phrase should not run" + event: issue_comment + fixture: .github/tests/events/should-run/issue_comment_no_trigger.json + expectations: + should_run: "false" + + - id: issue-comment-closed-pr + description: "Issue comment on closed PR should not run" + event: issue_comment + fixture: .github/tests/events/should-run/issue_comment_closed_pr.json + expectations: + should_run: "false" + + - id: issue-comment-closed-issue + description: "Issue comment on closed issue (not a PR) should not run" + event: issue_comment + fixture: .github/tests/events/should-run/issue_comment_closed_issue.json + expectations: + should_run: "false" diff --git a/.github/tests/workflows/check-permissions-template.yaml b/.github/tests/workflows/check-permissions-template.yaml new file mode 100644 index 0000000..72173db --- /dev/null +++ b/.github/tests/workflows/check-permissions-template.yaml @@ -0,0 +1,57 @@ +name: Check-permissions template + +on: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + # Test the check-permissions action + - id: check-permissions + uses: ./.github/actions/utils/check-permissions + continue-on-error: true # Don't fail the test if permissions check fails + + # Validate the results + - name: Validate permissions check behavior + shell: bash + env: + EXPECT_SHOULD_PASS: ${{ env.EXPECT_SHOULD_PASS }} + run: | + set -e + + # Get the outcome of the permissions check + OUTCOME="${{ steps.check-permissions.outcome }}" + CONCLUSION="${{ steps.check-permissions.conclusion }}" + + echo "::group::Permissions Check Results" + echo "Outcome: $OUTCOME" + echo "Conclusion: $CONCLUSION" + echo "Expected to pass: $EXPECT_SHOULD_PASS" + echo "Actor: ${{ github.actor }}" + echo "Repository owner: ${{ github.repository_owner }}" + echo "Repository owner type: ${{ github.event.repository.owner.type }}" + echo "::endgroup::" + + # Validate outcome matches expectation + if [[ "$EXPECT_SHOULD_PASS" == "true" ]]; then + if [[ "$OUTCOME" == "success" ]]; then + echo "✅ Expected success and got success" + else + echo "❌ Expected success but got $OUTCOME" + exit 1 + fi + elif [[ "$EXPECT_SHOULD_PASS" == "false" ]]; then + if [[ "$OUTCOME" == "failure" ]]; then + echo "✅ Expected failure and got failure" + else + echo "❌ Expected failure but got $OUTCOME" + exit 1 + fi + else + echo "⚠️ EXPECT_SHOULD_PASS not set - only validating action execution" + fi + + echo "✅ Permissions check validation passed" diff --git a/.github/tests/workflows/should-run-template.yaml b/.github/tests/workflows/should-run-template.yaml new file mode 100644 index 0000000..0c3842e --- /dev/null +++ b/.github/tests/workflows/should-run-template.yaml @@ -0,0 +1,37 @@ +name: Should-run template + +on: + push: + issue_comment: + types: + - created + workflow_dispatch: + pull_request: + +jobs: + sut: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - id: should_run + uses: ./.github/actions/utils/should-run + + - name: Assert expected outputs + shell: bash + env: + EXPECT_SHOULD_RUN: ${{ env.EXPECT_SHOULD_RUN }} + run: | + set -euo pipefail + + ACTUAL_SHOULD_RUN='${{ steps.should_run.outputs.shouldRun }}' + + echo "::group::Assertion details" + printf 'ACTUAL_SHOULD_RUN=%q\n' "$ACTUAL_SHOULD_RUN" + printf 'EXPECT_SHOULD_RUN=%q\n' "$EXPECT_SHOULD_RUN" + echo "::endgroup::" + + if [[ "${EXPECT_SHOULD_RUN+defined}" == "defined" && "$ACTUAL_SHOULD_RUN" != "$EXPECT_SHOULD_RUN" ]]; then + echo "❌ shouldRun mismatch"; exit 1 + fi + echo "✅ Assertions passed" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7938caa..69f4abb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: Lint for Actions directory +name: Lint on: pull_request: @@ -7,6 +7,7 @@ on: push: branches: - "main" + - "release-*" permissions: contents: read diff --git a/.github/workflows/test-dependencies.yml b/.github/workflows/test-dependencies.yml index 7548bb6..712ccc6 100644 --- a/.github/workflows/test-dependencies.yml +++ b/.github/workflows/test-dependencies.yml @@ -7,6 +7,7 @@ on: push: branches: - "main" + - "release-*" tags: - "*" diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 3d7cd05..0e8285b 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -7,6 +7,7 @@ on: push: branches: - "main" + - "release-*" tags: - "*" diff --git a/.github/workflows/test-utils.yml b/.github/workflows/test-utils.yml new file mode 100644 index 0000000..5fa7482 --- /dev/null +++ b/.github/workflows/test-utils.yml @@ -0,0 +1,192 @@ +name: Test Utils Actions + +on: + pull_request: + branches: + - "*" + push: + branches: + - "main" + - "release-*" + +permissions: + contents: read + +jobs: + test-check-permissions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + # Install dependencies + - name: Install act + run: | + # Install act for workflow testing + curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash + sudo install -m 0755 ./bin/act /usr/local/bin/act + + - name: Install yq + uses: ./.github/actions/dependencies/install-yq + with: + version: "v4.6.3" + + # Test all check-permissions scenarios + - name: Test check-permissions action scenarios + run: | + set -e + + SCENARIOS_FILE=".github/tests/scenarios/check-permissions.yaml" + WORKFLOW=".github/tests/workflows/check-permissions-template.yaml" + + echo "🔐 Running check-permissions action tests..." + echo "📁 Loading scenarios from: $SCENARIOS_FILE" + + # Get total number of scenarios + TOTAL=$(yq eval '.scenarios | length' "$SCENARIOS_FILE") + echo "📊 Found $TOTAL test scenarios" + echo + echo "⚠️ Note: These tests validate action structure and input handling." + echo " GitHub API permission checks depend on actual repository permissions." + echo + + # Initialize overall result tracker + overall_result=true + + # Loop through each scenario + for i in $(seq 0 $((TOTAL - 1))); do + # Extract scenario details using yq + id=$(yq eval ".scenarios[$i].id" "$SCENARIOS_FILE") + description=$(yq eval ".scenarios[$i].description" "$SCENARIOS_FILE") + event=$(yq eval ".scenarios[$i].event" "$SCENARIOS_FILE") + fixture=$(yq eval ".scenarios[$i].fixture" "$SCENARIOS_FILE") + + echo "───────────────────────────────────────" + echo "🔍 Scenario $((i + 1))/$TOTAL: $id" + echo " Description: $description" + echo " Event: $event" + echo " Fixture: $fixture" + + # Build environment variables from expectations + env_args="" + + # Get all expectation keys and build env vars + expectation_keys=$(yq eval ".scenarios[$i].expectations | keys | .[]" "$SCENARIOS_FILE") + for key in $expectation_keys; do + value=$(yq eval ".scenarios[$i].expectations.$key" "$SCENARIOS_FILE") + env_key="EXPECT_$(echo "$key" | tr '[:lower:]' '[:upper:]')" + env_args="$env_args --env $env_key=\"$value\"" + done + + # Extract actor from event fixture for proper GITHUB_ACTOR override + actor=$(yq eval '.actor' "$fixture") + echo " 👤 Actor from fixture: $actor" + + # Run act with the scenario + echo "▶️ Running test..." + + # Override GITHUB_ACTOR to match the actor in the event fixture + actor_args="--env GITHUB_ACTOR=\"$actor\"" + token_args="-s GITHUB_TOKEN=\"${{ secrets.GITHUB_TOKEN }}\"" + + if eval "act '$event' -W '$WORKFLOW' -e '$fixture' -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-22.04 --pull=false $env_args $actor_args $token_args"; then + echo "✅ $id completed" + else + echo "❌ $id failed" + overall_result=false + fi + # Print blank line for better readability + echo + done + + if [ "$overall_result" = "false" ]; then + echo "There are some test ❌. Please check the logs for more details." + exit 1 + fi + + echo "───────────────────────────────────────" + echo "🎉 All $TOTAL check-permissions scenarios completed!" + echo " Action structure and input handling validated ✅" + + test-should-run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + # Install dependencies + - name: Install act + run: | + # Install act for workflow testing + curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash + sudo install -m 0755 ./bin/act /usr/local/bin/act + + - name: Install yq + uses: ./.github/actions/dependencies/install-yq + with: + version: "v4.6.3" + + # Test all should-run scenarios + - name: Test should-run action scenarios + run: | + set -e + + SCENARIOS_FILE=".github/tests/scenarios/should-run.yaml" + WORKFLOW=".github/tests/workflows/should-run-template.yaml" + + echo "🚦 Running should-run action tests..." + echo "📁 Loading scenarios from: $SCENARIOS_FILE" + + # Get total number of scenarios + TOTAL=$(yq eval '.scenarios | length' "$SCENARIOS_FILE") + echo "📊 Found $TOTAL test scenarios" + echo + + # Initialize overall result tracker + overall_result=true + + # Loop through each scenario + for i in $(seq 0 $((TOTAL - 1))); do + # Extract scenario details using yq + id=$(yq eval ".scenarios[$i].id" "$SCENARIOS_FILE") + description=$(yq eval ".scenarios[$i].description" "$SCENARIOS_FILE") + event=$(yq eval ".scenarios[$i].event" "$SCENARIOS_FILE") + fixture=$(yq eval ".scenarios[$i].fixture" "$SCENARIOS_FILE") + + echo "───────────────────────────────────────" + echo "🔍 Scenario $((i + 1))/$TOTAL: $id" + echo " Description: $description" + echo " Event: $event" + echo " Fixture: $fixture" + + # Build environment variables from expectations + env_args="" + + # Get all expectation keys and build env vars + expectation_keys=$(yq eval ".scenarios[$i].expectations | keys | .[]" "$SCENARIOS_FILE") + for key in $expectation_keys; do + value=$(yq eval ".scenarios[$i].expectations.$key" "$SCENARIOS_FILE") + env_key="EXPECT_$(echo "$key" | tr '[:lower:]' '[:upper:]')" + env_args="$env_args --env $env_key=\"$value\"" + done + + token_args="-s GITHUB_TOKEN=\"${{ secrets.GITHUB_TOKEN }}\"" + + # Run act with the scenario + echo "▶️ Running test..." + + if eval "act '$event' -W '$WORKFLOW' -e '$fixture' -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-22.04 --pull=false $env_args $token_args"; then + echo "✅ $id passed" + else + echo "❌ $id failed" + overall_result=false + fi + # Print blank line for better readability + echo + done + + if [ "$overall_result" = "false" ]; then + echo "There are some test ❌. Please check the logs for more details." + exit 1 + fi + + echo "───────────────────────────────────────" + echo "🎉 All $TOTAL should-run scenarios passed!" \ No newline at end of file diff --git a/README.md b/README.md index 45ba8c7..da7f6e9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![Build Status - dependencies](https://github.com/strimzi/github-actions/actions/workflows/test-dependencies.yml/badge.svg)](https://github.com/strimzi/github-actions/actions/workflows/test-dependencies.yml) [![Build Status - integrations](https://github.com/strimzi/github-actions/actions/workflows/test-integrations.yml/badge.svg)](https://github.com/strimzi/github-actions/actions/workflows/test-integrations.yml) +[![Build Status - utils](https://github.com/strimzi/github-actions/actions/workflows/test-utils.yml/badge.svg)](https://github.com/strimzi/github-actions/actions/workflows/test-utils.yml) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Twitter Follow](https://img.shields.io/twitter/follow/strimziio?style=social)](https://twitter.com/strimziio) @@ -47,6 +48,16 @@ Actions for building, testing, and releasing Strimzi components. > The `build-binaries` action supports an `clusterOperatorBuild` input (default `false`) that enables Strimzi Kafka Operator specific build steps — Helm chart generation, CRD distribution, dashboard setup, documentation checks, and uncommitted changes verification. > Other repositories should leave this disabled. +### Utils Actions + +Actions used as utils mostly in operators repository. + +| Action | Description | Key Inputs | +|----------------------------|---------------------------------------------------------------------------|------------| +| `utils/check-permissions` | Check whether users who leave the comment has rights to trigger actions | none | +| `utils/determine-ref` | Determine checkout ref based on PR metadata | none | +| `utils/should-run` | Determine whether STs pipeline should be run or not based on comment body | none | + ## Test Workflows ### `test-dependencies.yml`