diff --git a/.claude/commands/review-pr.md b/.claude/commands/review-pr.md index 2571dadb7..eda1665ec 100644 --- a/.claude/commands/review-pr.md +++ b/.claude/commands/review-pr.md @@ -5,6 +5,7 @@ description: Review the current pull request with comprehensive code analysis You are conducting a thorough pull request code review for the Bitwarden gh-actions repository. ## Current Context + - Repository: bitwarden/gh-actions - This is a collection of reusable GitHub Actions workflows and custom actions - The code must follow Bitwarden's workflow linter rules @@ -15,12 +16,14 @@ You are conducting a thorough pull request code review for the Bitwarden gh-acti Perform a comprehensive review of the current PR with focus on: ### 1. **Code Quality & Best Practices** + - Adherence to GitHub Actions best practices - Proper error handling and validation - Code maintainability and clarity - Appropriate use of GitHub Actions syntax ### 2. **Security Implications** + - No hardcoded secrets or credentials - Proper permission scoping - Input validation and sanitization @@ -28,7 +31,9 @@ Perform a comprehensive review of the current PR with focus on: - Safe handling of user-provided data ### 3. **Workflow Linter Compliance** + Verify compliance with Bitwarden workflow linter rules: + - Actions pinned to commit SHA with version comment - Permissions explicitly defined - Runner versions pinned (e.g., ubuntu-24.04) @@ -36,12 +41,14 @@ Verify compliance with Bitwarden workflow linter rules: - Only approved actions are used ### 4. **Performance & Efficiency** + - Appropriate caching strategies - Parallel job execution where possible - Minimal redundant operations - Efficient use of GitHub Actions resources ### 5. **Testing & Validation** + - Adequate test coverage for new features - Test workflows follow established patterns - Integration with existing test infrastructure @@ -51,20 +58,24 @@ Verify compliance with Bitwarden workflow linter rules: Provide a structured review with: 1. **Summary of Changes** + - High-level overview of what this PR accomplishes - Key files modified and their impact 2. **Critical Issues** (if any) + - Security vulnerabilities - Breaking changes - Non-compliant code that must be fixed 3. **Suggested Improvements** + - Optimization opportunities - Better patterns or approaches - Documentation enhancements 4. **Good Practices Observed** + - Notable positive aspects (be concise) - Correct security implementations - Well-structured code diff --git a/.claude/prompts/review-code.md b/.claude/prompts/review-code.md index 72905852c..4e5f40b27 100644 --- a/.claude/prompts/review-code.md +++ b/.claude/prompts/review-code.md @@ -1,4 +1,5 @@ Please review this pull request with a focus on: + - Code quality and best practices - Potential bugs or issues - Security implications @@ -7,6 +8,7 @@ Please review this pull request with a focus on: Note: The PR branch is already checked out in the current working directory. Provide a comprehensive review including: + - Summary of changes since last review - Critical issues found (be thorough) - Suggested improvements (be thorough) @@ -15,6 +17,7 @@ Provide a comprehensive review including: - Leverage collapsible
sections where appropriate for lengthy explanations or code snippets to enhance human readability When reviewing subsequent commits: + - Track status of previously identified issues (fixed/unfixed/reopened) - Identify NEW problems introduced since last review - Note if fixes introduced new issues diff --git a/.editorconfig b/.editorconfig index 0ad1a4ee2..22f821754 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,6 +14,13 @@ trim_trailing_whitespace = true insert_final_newline = true guidelines = 120 -# JS files +# JSON files [*.{json,yml}] indent_size = 2 + +# JS / TS / Markdown +[*.{js,ts,md}] +charset = utf-8 +indent_style = space +indent_size = 2 +quote_type = single diff --git a/.github/templates/workflow-templates/example.yaml b/.github/templates/workflow-templates/example.yaml index 088b939bd..a5e2db312 100644 --- a/.github/templates/workflow-templates/example.yaml +++ b/.github/templates/workflow-templates/example.yaml @@ -1,5 +1,5 @@ -# Workflow templates are based on starter workflows provided by github at -# https://github.com/actions/starter-workflows/tree/main and customized to +# Workflow templates are based on starter workflows provided by github at +# https://github.com/actions/starter-workflows/tree/main and customized to # represent common practices used on ACME repositories. # This imaginary workflow runs two steps and illustrates a number of options that we use throughout workflows in the Bitwarden repositories @@ -7,94 +7,102 @@ name: Build on: # Describes when to run the workflow - # https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows + # https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows - workflow_dispatch: # When triggered manually + workflow_dispatch: # When triggered manually - push: # On push to the following branches. Temporarily add a development branch to prompt workflow runs for troubleshooting - branches: ["main", "rc", "hotfix-rc"] - paths-ignore: # Updates to these directories or files will not trigger a workflow run - - ".github/workflows/**" + push: # On push to the following branches. Temporarily add a development branch to prompt workflow runs for troubleshooting + branches: ["main", "rc", "hotfix-rc"] + paths-ignore: # Updates to these directories or files will not trigger a workflow run + - ".github/workflows/**" - # Pull_request_target: #We strongly discourage using this unless absolutely necessary as it requires access to certain Github secrets. + # Pull_request_target: #We strongly discourage using this unless absolutely necessary as it requires access to certain Github secrets. # If using this, include the .github/workflows/check-run.yml job and target only the main branch # More info at https://github.blog/news-insights/product-news/github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks - pull_request: # When a pull request event occurs - types: [opened, synchronize, unlabeled, labeled, unlabeled, reopened, edited] - branches: ["main"] # Branches where a pull request will trigger the workflow + pull_request: # When a pull request event occurs + types: + [ + opened, + synchronize, + unlabeled, + labeled, + unlabeled, + reopened, + edited, + ] + branches: ["main"] # Branches where a pull request will trigger the workflow + release: # Runs your workflow when release activity in your repository occurs + types: [published, created] - release: # Runs your workflow when release activity in your repository occurs - types: [published, created] + merge_group: # Runs required status checks on merge groups created by merge queue + types: [checks_requested] - merge_group: # Runs required status checks on merge groups created by merge queue - types: [checks_requested] + repository_dispatch: # Runs when a webook event triggers a workflow from outside of github + types: [contentful-publish] # Optional, limit repository dispatch events to those in a specified list - repository_dispatch: # Runs when a webook event triggers a workflow from outside of github - types: [contentful-publish] # Optional, limit repository dispatch events to those in a specified list - - workflow_call: # Workflow can be called by another workflow + workflow_call: # Workflow can be called by another workflow env: # Environment variables set for this step but not accessible by all workflows, steps or jobs. - _AZ_REGISTRY: "ACMEprod.azurecr.io" - INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}" + _AZ_REGISTRY: "ACMEprod.azurecr.io" + INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}" jobs: # A workflow run is made up of one or more jobs that can run sequentially or in parallel - first-job: - name: First Job Name - uses: ./.github/templates/workflow-templates/example-references/_version.yml # Path to an existing github action - if: github.event.pull_request.draft == false # prevent part of a job from running on a draft PR - secrets: inherit # When called by another workflow, pass all the calling workflow's secrets to the called workflow - # "secrets" is only available for a reusable workflow call with "uses" - strategy: # Create multiple job runs for each of a set of variables - fail-fast: false # If true, cancel entire run if any job in the matrix fails - matrix: # Matrix of variables used to define multiple job runs - include: - - project_name: Admin - base_path: ./src - node: true # Enables steps with if: ${{ matrix.node }} - - # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token - permissions: # Sets permissions of the GITHUB_TOKEN - security-events: write # Allow actions to upload results to Github - id-token: write # Required to fetch an OpenID Connect (OIDC) token - contents: read # For actions/checkout to fetch code - deployments: write # Permits an action to create a new deployment - issues: write # Permits an action to create a new issue - checks: write # Permits an action to create a check run - actions: write # Permits an action to cancel a workflow run - packages: read # Permits an action to access packages on GitHub Packages - pull-requests: write # Permits an action to add a label to a pull request - - # steps: when a reusable workflow is called with "uses", "steps" is not available - second-job: - name: Second Job Name - runs-on: ubuntu-22.04 # The type of runner that the job will run on, not available if "uses" is used - defaults: - run: # Set the default shell and working directory - shell: bash - working-directory: "home/WorkingDirectory" - - needs: - - first-job # This job will wait until first-job completes - # # # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/setting-a-default-shell-and-working-directory - steps: - - name: Descriptive step name - # NOT RECOMMENDED if: always() # run even if previous steps failed or the workflow is canceled, this can cause a workflow run to hang indefinitely - if: failure() # run when any previous step of a job fails - # if: '!cancelled()' # run even if previous steps failed - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 Always pin a public action version to a full git SHA, followed by the version number in a comment. Version pins are insecure and can introduce vulnerabilities into workflows. - with: # Parameters specific to this action that need to be defined in order for the step to be completed - fetch-depth: 0 # Full git history for actions that rely on whether a change has occurred - ref: ${{ github.event.pull_request.head.sha }} - creds: ${{ secrets.SECRETS_OR_CREDENTIALS }} - - name: Another descriptive step name - # Run a script instead of an existing github action - run: | - whoami - dotnet --info - node --version - npm --version - echo "GitHub ref: $GITHUB_REF" - echo "GitHub event: $GITHUB_EVENT" + first-job: + name: First Job Name + uses: ./.github/templates/workflow-templates/example-references/_version.yml # Path to an existing github action + if: github.event.pull_request.draft == false # prevent part of a job from running on a draft PR + secrets: inherit # When called by another workflow, pass all the calling workflow's secrets to the called workflow + # "secrets" is only available for a reusable workflow call with "uses" + strategy: # Create multiple job runs for each of a set of variables + fail-fast: false # If true, cancel entire run if any job in the matrix fails + matrix: # Matrix of variables used to define multiple job runs + include: + - project_name: Admin + base_path: ./src + node: true # Enables steps with if: ${{ matrix.node }} + + # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token + permissions: # Sets permissions of the GITHUB_TOKEN + security-events: write # Allow actions to upload results to Github + id-token: write # Required to fetch an OpenID Connect (OIDC) token + contents: read # For actions/checkout to fetch code + deployments: write # Permits an action to create a new deployment + issues: write # Permits an action to create a new issue + checks: write # Permits an action to create a check run + actions: write # Permits an action to cancel a workflow run + packages: read # Permits an action to access packages on GitHub Packages + pull-requests: write # Permits an action to add a label to a pull request + + # steps: when a reusable workflow is called with "uses", "steps" is not available + second-job: + name: Second Job Name + runs-on: ubuntu-22.04 # The type of runner that the job will run on, not available if "uses" is used + defaults: + run: # Set the default shell and working directory + shell: bash + working-directory: "home/WorkingDirectory" + + needs: + - first-job # This job will wait until first-job completes + # # # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/setting-a-default-shell-and-working-directory + steps: + - name: Descriptive step name + # NOT RECOMMENDED if: always() # run even if previous steps failed or the workflow is canceled, this can cause a workflow run to hang indefinitely + if: failure() # run when any previous step of a job fails + # if: '!cancelled()' # run even if previous steps failed + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 Always pin a public action version to a full git SHA, followed by the version number in a comment. Version pins are insecure and can introduce vulnerabilities into workflows. + with: # Parameters specific to this action that need to be defined in order for the step to be completed + fetch-depth: 0 # Full git history for actions that rely on whether a change has occurred + ref: ${{ github.event.pull_request.head.sha }} + creds: ${{ secrets.SECRETS_OR_CREDENTIALS }} + - name: Another descriptive step name + # Run a script instead of an existing github action + run: | + whoami + dotnet --info + node --version + npm --version + echo "GitHub ref: $GITHUB_REF" + echo "GitHub event: $GITHUB_EVENT" diff --git a/.github/workflows/_checkmarx.yml b/.github/workflows/_checkmarx.yml index ac86e6f07..8801a1cd2 100644 --- a/.github/workflows/_checkmarx.yml +++ b/.github/workflows/_checkmarx.yml @@ -36,6 +36,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: Log in to Azure uses: bitwarden/gh-actions/azure-login@main diff --git a/.github/workflows/_enforce-labels.yml b/.github/workflows/_enforce-labels.yml index 23c823923..c2cedda91 100644 --- a/.github/workflows/_enforce-labels.yml +++ b/.github/workflows/_enforce-labels.yml @@ -14,5 +14,5 @@ jobs: - name: Check for label run: | echo "PRs with the hold label cannot be merged" - echo "### :x: PRs with the hold label cannot be merged" >> $GITHUB_STEP_SUMMARY + echo "### :x: PRs with the hold label cannot be merged" >> "$GITHUB_STEP_SUMMARY" exit 1 diff --git a/.github/workflows/_ephemeral_environment_manager.yml b/.github/workflows/_ephemeral_environment_manager.yml index 1995c36ab..409064d75 100644 --- a/.github/workflows/_ephemeral_environment_manager.yml +++ b/.github/workflows/_ephemeral_environment_manager.yml @@ -70,15 +70,16 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: repository: bitwarden/ephemeral-environment-charts - token: '${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}' + token: "${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}" + persist-credentials: true - name: Create Branch env: BRANCH_NAME: ee-config-${{ inputs.project }}-${{ inputs.pull_request_number }} run: | - if ! git rev-parse --verify origin/${{ env.BRANCH_NAME }}; then - git checkout -b ${{ env.BRANCH_NAME }} - git push origin ${{ env.BRANCH_NAME }} + if ! git rev-parse --verify "origin/${BRANCH_NAME}"; then + git checkout -b "${BRANCH_NAME}" + git push origin "${BRANCH_NAME}" fi cleanup: @@ -112,20 +113,26 @@ jobs: with: repository: bitwarden/${{ inputs.project }} ref: ${{ inputs.ephemeral_env_branch }} - token: '${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}' + token: "${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}" + persist-credentials: true - name: Remove config working-directory: ephemeral-environments - run: rm -f ${{ inputs.ephemeral_env_branch }}.yaml + env: + BRANCH_NAME: ${{ inputs.ephemeral_env_branch }} + run: rm -f "$BRANCH_NAME.yaml" - name: Commit changes to ${{ inputs.ephemeral_env_branch }} working-directory: ephemeral-environments + env: + BOT_EMAIL: ${{ steps.retrieve-secrets.outputs.github-bitwarden-devops-bot-email }} + BRANCH_NAME: ${{ inputs.ephemeral_env_branch }} run: | - git config --local user.email "${{ steps.retrieve-secrets.outputs.github-bitwarden-devops-bot-email }}" - git config --local user.name "${{ env._BOT_NAME }}" + git config --local user.email "$BOT_EMAIL" + git config --local user.name "$_BOT_NAME" - git add ${{ inputs.ephemeral_env_branch }}.yaml - git commit -m "Removed ${{ inputs.ephemeral_env_branch }}.yaml config." + git add "$BRANCH_NAME.yaml" + git commit -m "Removed $BRANCH_NAME.yaml config." git push sync-env: @@ -152,9 +159,9 @@ jobs: with: keyvault: ${{ env._KEY_VAULT }} secrets: | - ephemeral-environment-argocd-cluster-url, - ephemeral-environment-argocd-cluster-api-secret, - ephemeral-environment-argocd-cluster-api-user + ephemeral-environment-argocd-cluster-url, + ephemeral-environment-argocd-cluster-api-secret, + ephemeral-environment-argocd-cluster-api-user - name: Log out from Azure uses: bitwarden/gh-actions/azure-logout@main @@ -169,16 +176,21 @@ jobs: rm argocd-linux-amd64 - name: Log into Argo CD cluster + env: + ARGOCD_CLUSTER_URL: ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-url }} + ARGOCD_CLUSTER_API_USER: ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-api-user }} + ARGOCD_CLUSTER_API_SECRET: ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-api-secret }} run: | - argocd login ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-url }} \ - --username ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-api-user }} \ - --password ${{ steps.retrieve-secrets.outputs.ephemeral-environment-argocd-cluster-api-secret }} + argocd login "${ARGOCD_CLUSTER_URL}" \ + --username "${ARGOCD_CLUSTER_API_USER}" \ + --password "${ARGOCD_CLUSTER_API_SECRET}" - name: Sync Argo CD application env: ARGOCD_OPTS: --grpc-web + PR_NUMBER: ${{ inputs.pull_request_number }} run: | - APP_NAME=$(argocd app list -o name | grep ${{ inputs.pull_request_number }}) + APP_NAME=$(argocd app list -o name | grep "${PR_NUMBER}") # Check if there's a running sync operation APP_SYNC_STATUS=$(argocd app get "$APP_NAME" --refresh -o json | jq -r '.status.operationState.phase') diff --git a/.github/workflows/_publish-mobile-github-release.yml b/.github/workflows/_publish-mobile-github-release.yml index 991930e68..f5e30fae3 100644 --- a/.github/workflows/_publish-mobile-github-release.yml +++ b/.github/workflows/_publish-mobile-github-release.yml @@ -8,7 +8,7 @@ on: type: string default: "" workflow_name: - description: 'Name of the workflow to check for previous runs (e.g. publish-github-release.yml)' + description: "Name of the workflow to check for previous runs (e.g. publish-github-release.yml)" type: string required: true credentials_filename: @@ -28,7 +28,7 @@ on: required: true dry_run: type: boolean - description: 'Run the workflow in dry-run mode without making any changes' + description: "Run the workflow in dry-run mode without making any changes" required: false default: false @@ -49,21 +49,26 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Get latest draft name id: get_latest_draft env: GITHUB_TOKEN: ${{ github.token }} + RELEASE_NAME: ${{ inputs.release_name }} run: | - latest_release=$(gh release list --json name,tagName,isDraft,isPrerelease -L 10 --jq 'first(.[] | select((.name | test("${{ inputs.release_name }}"; "i")) and (.isDraft == true)))') + latest_release=$( + gh release list --json name,tagName,isDraft,isPrerelease -L 10 \ + --jq "first(.[] | select((.name | test(\"$RELEASE_NAME\"; \"i\")) and (.isDraft == true)))" + ) is_latest_draft="false" if [ "$latest_release" != "null" ] && [ -n "$latest_release" ]; then - is_latest_draft=$(jq -r '.isDraft' <<< $latest_release) + is_latest_draft=$(jq -r '.isDraft' <<< "$latest_release") fi - echo "is_latest_draft=$is_latest_draft" >> $GITHUB_OUTPUT + echo "is_latest_draft=$is_latest_draft" >> "$GITHUB_OUTPUT" if [ "$is_latest_draft" != "true" ]; then echo "No draft found" @@ -74,17 +79,17 @@ jobs: exit 0 fi - latest_draft_tag=$(jq -r '.tagName' <<< $latest_release) - echo "latest_draft_tag=$latest_draft_tag" >> $GITHUB_OUTPUT + latest_draft_tag=$(jq -r '.tagName' <<< "$latest_release") + echo "latest_draft_tag=$latest_draft_tag" >> "$GITHUB_OUTPUT" - latest_draft_version_name=$(echo "$latest_release" | jq -r '.name' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') - echo "latest_draft_version_name=$latest_draft_version_name" >> $GITHUB_OUTPUT + latest_draft_version_name=$(jq -r '.name' <<< "$latest_release" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') + echo "latest_draft_version_name=$latest_draft_version_name" >> "$GITHUB_OUTPUT" - latest_draft_version_number=$(echo "$latest_release" | jq -r '.name' | grep -oE '\([0-9]+\)' | sed 's/[()]//g') - echo "latest_draft_version_number=$latest_draft_version_number" >> $GITHUB_OUTPUT + latest_draft_version_number=$(jq -r '.name' <<< "$latest_release" | grep -oE '\([0-9]+\)' | sed 's/[()]//g') + echo "latest_draft_version_number=$latest_draft_version_number" >> "$GITHUB_OUTPUT" - latest_draft_name=$(jq -r '.name' <<< $latest_release) - echo "latest_draft_name=$latest_draft_name" >> $GITHUB_OUTPUT + latest_draft_name=$(jq -r '.name' <<< "$latest_release") + echo "latest_draft_name=$latest_draft_name" >> "$GITHUB_OUTPUT" # Retrieve the previous run ID and run state to determine the status of the last workflow execution. # This is done to prevent the workflow from publishing a release that was already published, @@ -95,22 +100,24 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - previous_run_id=$(gh run list --workflow=$_WORKFLOW_NAME --status=success --limit 1 --json databaseId --jq '.[0].databaseId // empty') + previous_run_id=$(gh run list --workflow="$_WORKFLOW_NAME" --status=success --limit 1 --json databaseId --jq '.[0].databaseId // empty') if [ -n "$previous_run_id" ] && [ "$previous_run_id" != "null" ]; then echo "Found previous successful scheduled run: $previous_run_id" - echo "previous_run_id=$previous_run_id" >> $GITHUB_OUTPUT - echo "has_previous_run=true" >> $GITHUB_OUTPUT + echo "previous_run_id=$previous_run_id" >> "$GITHUB_OUTPUT" + echo "has_previous_run=true" >> "$GITHUB_OUTPUT" else echo "No previous successful scheduled run found" - echo "has_previous_run=false" >> $GITHUB_OUTPUT + echo "has_previous_run=false" >> "$GITHUB_OUTPUT" fi - name: Compose artifact name id: compose_artifact_name + env: + RELEASE_NAME: ${{ inputs.release_name }} run: | - artifact_name=$(echo "release-info-${{ inputs.release_name }}" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g') - echo "artifact_name=$artifact_name" >> $GITHUB_OUTPUT + artifact_name=$(echo "release-info-$RELEASE_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g') + echo "artifact_name=$artifact_name" >> "$GITHUB_OUTPUT" - name: Download previous run state id: previous_state @@ -126,22 +133,24 @@ jobs: id: parse_previous_state if: steps.get_previous_run.outputs.has_previous_run == 'true' run: | - if [ -f "release-info.json" ]; then + if [[ -f "release-info.json" ]]; then previous_release_tag=$(jq -r '.release_tag // empty' release-info.json) previous_initial_state=$(jq -r '.initial_state // empty' release-info.json) previous_changed_to=$(jq -r '.changed_to_state // empty' release-info.json) - echo "previous_release_tag=$previous_release_tag" >> $GITHUB_OUTPUT - echo "previous_initial_state=$previous_initial_state" >> $GITHUB_OUTPUT - echo "previous_changed_to=$previous_changed_to" >> $GITHUB_OUTPUT - echo "previous_timestamp=$previous_timestamp" >> $GITHUB_OUTPUT - echo "has_previous_state=true" >> $GITHUB_OUTPUT + cat >>"$GITHUB_OUTPUT" <> $GITHUB_OUTPUT + echo "has_previous_state=false" >> "$GITHUB_OUTPUT" fi - name: Check if release was already processed @@ -155,23 +164,28 @@ jobs: run: | should_skip=false - if [ "$HAS_PREVIOUS_STATE" == "true" ] && [ "$PREVIOUS_RELEASE" != "" ] && [ "$CURRENT_RELEASE" == "$PREVIOUS_RELEASE" ]; then - if [ "$PREVIOUS_CHANGED_TO" == "published" ] || ([ "$PREVIOUS_INITIAL_STATE" == "published" ] && [ "$PREVIOUS_CHANGED_TO" == "none" ]); then - echo "::error:: Release $CURRENT_RELEASE was already processed and published by this workflow" - echo "This suggests the release was manually reverted to draft after being published" - echo "Skipping to prevent duplicate processing" + if [[ "$HAS_PREVIOUS_STATE" == "true" && -n "$PREVIOUS_RELEASE" && "$CURRENT_RELEASE" == "$PREVIOUS_RELEASE" ]]; then + if [[ "$PREVIOUS_CHANGED_TO" == "published" || ( "$PREVIOUS_INITIAL_STATE" == "published" && "$PREVIOUS_CHANGED_TO" == "none" ) ]]; then + + cat <> $GITHUB_STEP_SUMMARY - echo "Release \`$CURRENT_RELEASE\` was already processed by this workflow." >> $GITHUB_STEP_SUMMARY - echo "To force reprocessing, either:" >> $GITHUB_STEP_SUMMARY - echo "- Use manual workflow dispatch" >> $GITHUB_STEP_SUMMARY - echo "- Create a new release version" >> $GITHUB_STEP_SUMMARY + cat >>"$GITHUB_STEP_SUMMARY" <> $GITHUB_OUTPUT + echo "should_skip=$should_skip" >> "$GITHUB_OUTPUT" - name: Configure Ruby if: steps.check_already_processed.outputs.should_skip == 'false' @@ -201,8 +215,8 @@ jobs: run: | mkdir -p ${{ github.workspace }}/secrets - az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ - --name $CREDENTIALS_FILE_NAME --file ${{ github.workspace }}/secrets/$CREDENTIALS_FILE_NAME --output none + az storage blob download --account-name "$ACCOUNT_NAME" --container-name "$CONTAINER_NAME" \ + --name "$CREDENTIALS_FILE_NAME" --file "${{ github.workspace }}/secrets/$CREDENTIALS_FILE_NAME" --output none - name: Log out from Azure uses: bitwarden/gh-actions/azure-logout@main @@ -212,42 +226,44 @@ jobs: id: get_store_versions env: CREDENTIALS_PATH: ${{ github.workspace }}/secrets/${{ inputs.credentials_filename }} + CHECK_RELEASE_COMMAND: ${{ inputs.check_release_command }} run: | echo "Running custom release check command..." - echo "Command: ${{ inputs.check_release_command }}" + echo "Command: $CHECK_RELEASE_COMMAND" - OUTPUT=$(eval "${{ inputs.check_release_command }}") + OUTPUT=$(eval "$CHECK_RELEASE_COMMAND") version_name=$(echo "$OUTPUT" | grep 'version_name: ' | cut -d' ' -f3) version_number=$(echo "$OUTPUT" | grep 'version_number: ' | cut -d' ' -f3) - echo "store_version_name=$version_name" >> $GITHUB_OUTPUT - echo "store_version_number=$version_number" >> $GITHUB_OUTPUT + echo "store_version_name=$version_name" >> "$GITHUB_OUTPUT" + echo "store_version_number=$version_number" >> "$GITHUB_OUTPUT" - name: Check if version is already released if: steps.check_already_processed.outputs.should_skip == 'false' id: check_version env: + PROJECT_TYPE: ${{ inputs.project_type }} LATEST_DRAFT_VERSION_NAME: ${{ steps.get_latest_draft.outputs.latest_draft_version_name }} LATEST_DRAFT_VERSION_NUMBER: ${{ steps.get_latest_draft.outputs.latest_draft_version_number }} STORE_VERSION_NAME: ${{ steps.get_store_versions.outputs.store_version_name }} STORE_VERSION_NUMBER: ${{ steps.get_store_versions.outputs.store_version_number }} run: | - if [ "${{ inputs.project_type }}" == "ios" ]; then + if [ "$PROJECT_TYPE" == "ios" ]; then if [ "$LATEST_DRAFT_VERSION_NAME" == "$STORE_VERSION_NAME" ] && [ "$LATEST_DRAFT_VERSION_NUMBER" == "$STORE_VERSION_NUMBER" ]; then echo "iOS: Version name $LATEST_DRAFT_VERSION_NAME and version number $LATEST_DRAFT_VERSION_NUMBER is already released on store" - echo "version_released=true" >> $GITHUB_OUTPUT + echo "version_released=true" >> "$GITHUB_OUTPUT" else echo "iOS: Version $LATEST_DRAFT_VERSION_NAME ($LATEST_DRAFT_VERSION_NUMBER) is not released on store. Latest version in the store is $STORE_VERSION_NAME ($STORE_VERSION_NUMBER)" - echo "version_released=false" >> $GITHUB_OUTPUT + echo "version_released=false" >> "$GITHUB_OUTPUT" fi else if [ "$LATEST_DRAFT_VERSION_NUMBER" == "$STORE_VERSION_NUMBER" ]; then echo "Version $LATEST_DRAFT_VERSION_NUMBER is already released on store" - echo "version_released=true" >> $GITHUB_OUTPUT + echo "version_released=true" >> "$GITHUB_OUTPUT" else echo "Version $LATEST_DRAFT_VERSION_NUMBER is not released on store. Latest version in the store is $STORE_VERSION_NUMBER, with version name: $STORE_VERSION_NAME" - echo "version_released=false" >> $GITHUB_OUTPUT + echo "version_released=false" >> "$GITHUB_OUTPUT" fi fi @@ -260,9 +276,9 @@ jobs: PRODUCT: ${{ inputs.release_name }} run: | if [ "$PRODUCT" = "Password Manager" ]; then - gh release edit $TAG --prerelease=false --latest --draft=false + gh release edit "$TAG" --prerelease=false --latest --draft=false else - gh release edit $TAG --prerelease=false --draft=false + gh release edit "$TAG" --prerelease=false --draft=false fi - name: Disable workflow if published @@ -279,29 +295,35 @@ jobs: fi - name: Create workflow state artifact + env: + IS_LATEST_DRAFT: ${{ steps.get_latest_draft.outputs.is_latest_draft }} + LATEST_DRAFT_VERSION_NAME: ${{ steps.get_latest_draft.outputs.latest_draft_version_name }} + PREVIOUS_RELEASE_TAG: ${{ steps.parse_previous_state.outputs.previous_release_tag }} + SHOULD_SKIP: ${{ steps.check_already_processed.outputs.should_skip }} + VERSION_RELEASED: ${{ steps.check_version.outputs.version_released }} run: | if [ -f "release-info.json" ]; then echo "release-info.json already exists, removing it" rm -f release-info.json fi - if [ "${{ steps.get_latest_draft.outputs.is_latest_draft }}" == "true" ]; then - release_tag="${{ steps.get_latest_draft.outputs.latest_draft_version_name }}" + if [ "$IS_LATEST_DRAFT" == "true" ]; then + release_tag="$LATEST_DRAFT_VERSION_NAME" else - release_tag="${{ steps.parse_previous_state.outputs.previous_release_tag }}" + release_tag="$PREVIOUS_RELEASE_TAG" fi - if [ "${{ steps.check_already_processed.outputs.should_skip }}" == "true" ]; then + if [ "$SHOULD_SKIP" == "true" ]; then initial_state="draft" changed_to_state="none" - elif [ "${{ steps.get_latest_draft.outputs.is_latest_draft }}" == "true" ] && [ "${{ steps.check_already_processed.outputs.should_skip }}" == "false" ]; then + elif [ "$IS_LATEST_DRAFT" == "true" ] && [ "$SHOULD_SKIP" == "false" ]; then initial_state="draft" - if [ "${{ steps.check_version.outputs.version_released }}" == "true" ]; then + if [ "$VERSION_RELEASED" == "true" ]; then changed_to_state="published" else changed_to_state="none" fi - elif [ "${{ steps.get_latest_draft.outputs.is_latest_draft }}" == "false" ]; then + elif [ "$IS_LATEST_DRAFT" == "false" ]; then initial_state="published" changed_to_state="none" fi @@ -314,9 +336,11 @@ jobs: echo "$json" > release-info.json - echo '```json' >> $GITHUB_STEP_SUMMARY - echo "$json" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY + cat >>"$GITHUB_STEP_SUMMARY" < - "-Dsonar.organization=${{ github.repository_owner }}" - "-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}" - ${{ contains(github.event_name, 'pull_request') && format('"-Dsonar.pullrequest.key={0}"', github.event.pull_request.number) || '' }} + SONAR_ARGS: >- + ${{ github.event_name == 'pull_request' && format('"-Dsonar.pullrequest.key={0}"', github.event.pull_request.number) || '' }} ${{ inputs.sonar-test-inclusions != '' && format('"-Dsonar.test.inclusions={0}"', inputs.sonar-test-inclusions) || '' }} ${{ inputs.sonar-exclusions != '' && format('"-Dsonar.exclusions={0}"', inputs.sonar-exclusions) || '' }} ${{ inputs.sonar-sources != '' && format('"-Dsonar.sources={0}"', inputs.sonar-sources) || '' }} ${{ inputs.sonar-tests != '' && format('"-Dsonar.tests={0}"', inputs.sonar-tests) || '' }} + with: + args: > + "-Dsonar.organization=${{ github.repository_owner }}" + "-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}" + ${{ env.SONAR_ARGS }} - name: Set up Java if: inputs.sonar-config == 'maven' || inputs.sonar-config == 'dotnet' diff --git a/.github/workflows/_version.yml b/.github/workflows/_version.yml index c307809ba..36548466e 100644 --- a/.github/workflows/_version.yml +++ b/.github/workflows/_version.yml @@ -28,6 +28,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Get PR ID id: pr @@ -39,11 +40,11 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $GH_TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }} | \ + "https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }}" | \ jq -r ".commit.message" ) ID=$(echo "$commit_message" | head -1 | grep -o "(#.*)" | grep -o "[0-9]*") - echo "id=$ID" >> $GITHUB_OUTPUT + echo "id=$ID" >> "$GITHUB_OUTPUT" - name: Get version bump type if: ${{ inputs.is-release }} @@ -57,24 +58,27 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $GH_TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/labels | \ - jq -r ".[].name" | grep "version" + "https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/labels" | \ + jq -r '.[].name' | grep "version" ) # Single Version label Enforcement (should go in CI...) - if [[ $(echo $version_tag | wc -w) -gt 1 ]]; then - echo "[!] multiple version labels found!" - exit 1 + tag_count=$(wc -w <<<"$version_tag") + if [[ $tag_count -gt 1 ]]; then + echo "[!] multiple version labels found!" + exit 1 fi - version_type=$(echo $version_tag | cut -d ":" -f 2) + version_type=$(cut -d ":" -f 2 <<<"$version_tag") + echo "Version Bump Type: $version_type" - echo "type=$version_type" >> $GITHUB_OUTPUT + echo "type=$version_type" >> "$GITHUB_OUTPUT" - name: Calculate next version id: calculate env: VERSION_TYPE: ${{ steps.bump-type.outputs.type }} + PR_ID: ${{ steps.pr.outputs.id }} run: | echo -e "\nCalculating next version..." @@ -82,27 +86,32 @@ jobs: latest_version=${latest_tag_version:1} # remove 'v' from tag version if [[ "${{ inputs.is-release }}" == "true" ]]; then - latest_major_version=$(echo $latest_version | cut -d "." -f 1) - latest_minor_version=$(echo $latest_version | cut -d "." -f 2) - latest_patch_version=$(echo $latest_version | cut -d "." -f 3) + latest_major_version=$(cut -d "." -f 1 <<<"$latest_version") + latest_minor_version=$(cut -d "." -f 2 <<<"$latest_version") + latest_patch_version=$(cut -d "." -f 3 <<<"$latest_version") - echo " latest_version: $latest_version" - echo " latest_major_version: $latest_major_version" - echo " latest_minor_version: $latest_minor_version" - echo " latest_patch_version: $latest_patch_version" + echo " latest_version: $latest_version" + echo " latest_major_version: $latest_major_version" + echo " latest_minor_version: $latest_minor_version" + echo " latest_patch_version: $latest_patch_version" - if [[ "$VERSION_TYPE" == "major" ]]; then - next_version="$(($latest_major_version + 1)).0.0" - elif [[ "$VERSION_TYPE" == "minor" ]]; then - next_version="${latest_major_version}.$(($latest_minor_version + 1)).0" - elif [[ "$VERSION_TYPE" == "patch" ]]; then - next_version="${latest_major_version}.${latest_minor_version}.$(($latest_patch_version + 1))" - else - next_version="$latest_version+${{ steps.pr.outputs.id }}" - fi + case "$VERSION_TYPE" in + major) + next_version="$((latest_major_version + 1)).0.0" + ;; + minor) + next_version="${latest_major_version}.$((latest_minor_version + 1)).0" + ;; + patch) + next_version="${latest_major_version}.${latest_minor_version}.$((latest_patch_version + 1))" + ;; + *) + next_version="${latest_version}+${PR_ID}" + ;; + esac echo "Next Version: $next_version" - echo "version=$next_version" >> $GITHUB_OUTPUT + echo "version=$next_version" >> "$GITHUB_OUTPUT" else - echo "version=$latest_version+${{ steps.pr.outputs.id }}" >> $GITHUB_OUTPUT + echo "version=$latest_version+$PR_ID" >> "$GITHUB_OUTPUT" fi diff --git a/.github/workflows/check-run.yml b/.github/workflows/check-run.yml index 61e19b1d0..f7c3fa979 100644 --- a/.github/workflows/check-run.yml +++ b/.github/workflows/check-run.yml @@ -26,8 +26,10 @@ jobs: if: | steps.get-permission.outputs.require-result == 'false' && github.triggering_actor != 'bw-ghapp[bot]' + env: + USER_PERMISSIONS: ${{ steps.get-permission.outputs.user-permission }} run: | - echo "User ${{ github.triggering_actor }} does not have the necessary access for this repository." - echo "Current permission level is ${{ steps.get-permission.outputs.user-permission }}." - echo "Job originally triggered by ${{ github.actor }}." + echo "User ${GITHUB_TRIGGERING_ACTOR} does not have the necessary access for this repository." + echo "Current permission level is ${USER_PERMISSIONS}." + echo "Job originally triggered by ${GITHUB_ACTOR}." exit 1 diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 887136669..7071bafa0 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -9,7 +9,7 @@ on: types: [opened, synchronize, reopened] branches-ignore: - main - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] types: [opened, synchronize, reopened] branches: - "main" diff --git a/.github/workflows/test-download-artifacts.yml b/.github/workflows/test-download-artifacts.yml index aa261e5aa..16af398ab 100644 --- a/.github/workflows/test-download-artifacts.yml +++ b/.github/workflows/test-download-artifacts.yml @@ -3,7 +3,7 @@ name: Test Download Artifacts Action on: workflow_dispatch: inputs: {} - workflow_run: + workflow_run: # zizmor: ignore[dangerous-triggers] workflows: - Upload Test Artifacts types: @@ -23,6 +23,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts @@ -34,8 +36,7 @@ jobs: - name: Test run: | cat artifact/sha - echo $GITHUB_SHA - + echo "$GITHUB_SHA" download-main: name: Download main @@ -44,6 +45,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts @@ -56,7 +59,7 @@ jobs: - name: Test run: | cat artifact/sha - echo $GITHUB_SHA + echo "$GITHUB_SHA" download-branch: name: Download current branch @@ -65,12 +68,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Extract branch name id: extract_branch run: | - branch=${GITHUB_REF#refs/heads/} - echo "branch=$branch" >> $GITHUB_OUTPUT + branch=${GITHUB_REF#refs/heads/} + echo "branch=$branch" >> "$GITHUB_OUTPUT" - name: Download uses: ./download-artifacts @@ -83,15 +88,20 @@ jobs: - name: Test run: | cat artifact/sha - echo $GITHUB_SHA + echo "$GITHUB_SHA" download-pr: name: Download Pull Request runs-on: ubuntu-22.04 + permissions: + contents: read + id-token: write if: github.event_name == 'pull_request' steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts @@ -104,8 +114,7 @@ jobs: - name: Test run: | cat artifact/sha - echo $GITHUB_SHA - + echo "$GITHUB_SHA" download-all: name: Download All @@ -113,6 +122,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts @@ -126,20 +137,21 @@ jobs: cat sha1 cat sha2 - download-multiple: name: Download Multiple runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts with: workflow: upload-test-artifacts.yml - artifacts: 'artifact1, - artifact2' + artifacts: "artifact1, + artifact2" - name: Test run: | @@ -147,19 +159,20 @@ jobs: cat sha1 cat sha2 - download-wildcard: name: Download Wildcard runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts with: workflow: upload-test-artifacts.yml - artifacts: '*.txt' + artifacts: "*.txt" - name: Test run: | @@ -167,13 +180,14 @@ jobs: cat sha1 cat sha2 - download-conclusion: name: Download Conclusion runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download uses: ./download-artifacts @@ -181,12 +195,12 @@ jobs: workflow: upload-test-artifacts.yml artifacts: artifact path: artifact - workflow_conclusion: '' + workflow_conclusion: "" - name: Test run: | cat artifact/sha - echo $GITHUB_SHA + echo "$GITHUB_SHA" download-outputs: name: Download outputs should not be empty @@ -194,6 +208,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Download id: download @@ -206,8 +222,8 @@ jobs: _ARTIFACT_BUILD_COMMIT: ${{ steps.download.outputs.artifact-build-commit }} run: | ls -atlh - echo $_ARTIFACT_BUILD_COMMIT - if [[-z "$_ARTIFACT_BUILD_COMMIT"]]; then + echo "$_ARTIFACT_BUILD_COMMIT" + if [[ -z "$_ARTIFACT_BUILD_COMMIT" ]]; then echo "artifact-build-commit is empty" exit 1 fi @@ -217,8 +233,8 @@ jobs: _ARTIFACT_BUILD_BRANCH: ${{ steps.download.outputs.artifact-build-branch }} run: | ls -atlh - echo $_ARTIFACT_BUILD_BRANCH - if [[-z "$_ARTIFACT_BUILD_BRANCH"]]; then + echo "$_ARTIFACT_BUILD_BRANCH" + if [[ -z "$_ARTIFACT_BUILD_BRANCH" ]]; then echo "artifact-build-branch is empty" exit 1 fi diff --git a/.github/workflows/test-get-secrets.yml b/.github/workflows/test-get-secrets.yml index 87d34c818..810841226 100644 --- a/.github/workflows/test-get-secrets.yml +++ b/.github/workflows/test-get-secrets.yml @@ -15,7 +15,6 @@ on: permissions: contents: read - id-token: write env: _TEST_SECRET_VALUE_1: Test Value 1 _TEST_SECRET_VALUE_2: Test Value 2 @@ -24,11 +23,15 @@ jobs: test-repo-secrets: name: Test Get Secrets runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write steps: - name: Check out repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Log in to Azure uses: ./azure-login # Use the local action for testing @@ -40,7 +43,7 @@ jobs: - name: Verify Azure Login id: verify-login run: | - az account show --query name --output tsv + az account show --query name --output tsv - name: Get KV Secrets id: get-kv-secrets @@ -59,12 +62,15 @@ jobs: az account show --query name --output tsv && (echo "Unexpectedly returned account name instead of being logged out" && exit 1) || echo "Successfully logged out of Azure" - name: Verify test secret value + env: + TEST_SECRET_1: ${{ steps.get-kv-secrets.outputs.test-secret-1 }} + TEST_SECRET_2: ${{ steps.get-kv-secrets.outputs.test-secret-2 }} run: | - if [[ "${{ steps.get-kv-secrets.outputs.test-secret-1 }}" != "$_TEST_SECRET_VALUE_1" ]]; then + if [[ "$TEST_SECRET_1" != "$_TEST_SECRET_VALUE_1" ]]; then echo "test-secret-1 value is not as expected" exit 1 fi - if [[ "${{ steps.get-kv-secrets.outputs.test-secret-2 }}" != "$_TEST_SECRET_VALUE_2" ]]; then + if [[ "$TEST_SECRET_2" != "$_TEST_SECRET_VALUE_2" ]]; then echo "test-secret-2 value is not as expected" exit 1 fi @@ -83,22 +89,51 @@ jobs: exit $exit_code fi + build-matrix: + # This is needed because the matrix is built before the env variables are created. This is a + # workaround to create the matrix at run-time, which feels only slightly less bad as hard-coding the test secret strings + name: Build Test Matrix + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - id: set-matrix + name: Set matrix output variable + # Create the matrix from JSON. GitHub requires the JSON to be a single line, so the "jq -c" makes a single-line compact JSON string, just in case + run: | + json=$(cat <> "$GITHUB_OUTPUT" + test-repo-secrets-matrix: name: Test Get Secrets - Matrix + needs: build-matrix strategy: fail-fast: false - matrix: - include: - - secret_key: test-secret-1 - secret_value: $_TEST_SECRET_VALUE_1 - - secret_key: test-secret-2 - secret_value: $_TEST_SECRET_VALUE_2 + matrix: ${{ fromJSON(needs.build-matrix.outputs.matrix) }} runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write steps: - name: Check out repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Log in to Azure uses: ./azure-login # Use the local action for testing @@ -119,9 +154,13 @@ jobs: uses: ./azure-logout # Use the local action for testing - name: Verify test secret value + env: + KV_SECRET_VALUE: ${{ steps.get-kv-secrets.outputs[matrix.secret_key] }} + MATRIX_SECRET_TEST_VALUE: ${{ matrix.secret_value }} + MATRIX_SECRET_KEY: ${{ matrix.secret_key }} run: | - if [[ "${{ steps.get-kv-secrets.outputs[matrix.secret_key] }}" != "${{ matrix.secret_value }}" ]]; then - echo "${{ matrix.secret_key }} value is not as expected" + if [[ "$KV_SECRET_VALUE" != "$MATRIX_SECRET_TEST_VALUE" ]]; then + echo "$MATRIX_SECRET_KEY value is not as expected" exit 1 fi echo "Test secret values checks successful!" diff --git a/.github/workflows/test-release-version-check.yml b/.github/workflows/test-release-version-check.yml index 4567caf41..df4969b18 100644 --- a/.github/workflows/test-release-version-check.yml +++ b/.github/workflows/test-release-version-check.yml @@ -21,50 +21,52 @@ jobs: fail-fast: false matrix: include: - - name: ts-semver-success + - name: ts_semver_success project-type: ts file: release-version-check/tests/fixtures/SemVer/package.json override-version: 1.1.0 - - name: ts-semver-fail + - name: ts_semver_fail project-type: ts file: release-version-check/tests/fixtures/SemVer/package.json override-version: 1.0.1 - - name: ts-calver-success + - name: ts_calver_success project-type: ts file: release-version-check/tests/fixtures/CalVer/package.json override-version: 2022.06.0 - - name: ts-calver-fail + - name: ts_calver_fail project-type: ts file: release-version-check/tests/fixtures/CalVer/package.json override-version: 2022.05.0 - - name: dotnet-calver-success + - name: dotnet_calver_success project-type: dotnet file: release-version-check/tests/fixtures/CalVer/Test.csproj override-version: 2022.06.0 - - name: dotnet-calver-fail + - name: dotnet_calver_fail project-type: dotnet file: release-version-check/tests/fixtures/CalVer/Test.csproj override-version: 2022.05.0 - - name: xamarin-calver-success + - name: xamarin_calver_success project-type: xamarin file: release-version-check/tests/fixtures/CalVer/Mobile-Android.xml override-version: 2022.05.1 - - name: xamarin-calver-fail + - name: xamarin_calver_fail project-type: xamarin file: release-version-check/tests/fixtures/CalVer/Mobile-Android.xml override-version: 2022.05.0 outputs: - ts-semver-success-status: ${{ steps.set-status.outputs.ts-semver-success }} - ts-semver-fail-status: ${{ steps.set-status.outputs.ts-semver-fail }} - ts-calver-success-status: ${{ steps.set-status.outputs.ts-calver-success }} - ts-calver-fail-status: ${{ steps.set-status.outputs.ts-calver-fail }} - dotnet-calver-success-status: ${{ steps.set-status.outputs.dotnet-calver-success }} - dotnet-calver-fail-status: ${{ steps.set-status.outputs.dotnet-calver-fail }} - xamarin-calver-success-status: ${{ steps.set-status.outputs.xamarin-calver-success }} - xamarin-calver-fail-status: ${{ steps.set-status.outputs.xamarin-calver-fail }} + ts_semver_success_status: ${{ steps.set-status.outputs.ts_semver_success }} + ts_semver_fail_status: ${{ steps.set-status.outputs.ts_semver_fail }} + ts_calver_success_status: ${{ steps.set-status.outputs.ts_calver_success }} + ts_calver_fail_status: ${{ steps.set-status.outputs.ts_calver_fail }} + dotnet_calver_success_status: ${{ steps.set-status.outputs.dotnet_calver_success }} + dotnet_calver_fail_status: ${{ steps.set-status.outputs.dotnet_calver_fail }} + xamarin_calver_success_status: ${{ steps.set-status.outputs.xamarin_calver_success }} + xamarin_calver_fail_status: ${{ steps.set-status.outputs.xamarin_calver_fail }} steps: - name: Checkout Branch uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Version Check - ${{ matrix.name }} id: run-version-check @@ -78,25 +80,37 @@ jobs: - name: Set Status id: set-status + env: + MATRIX_NAME: ${{ matrix.name }} + VERSION_CHECK_STATUS: ${{ steps.run-version-check.outputs.status }} run: | - echo "Status Status - ${{ matrix.name }}: ${{ steps.run-version-check.outputs.status }}" - echo "${{ matrix.name }}=${{ steps.run-version-check.outputs.status }}" >> $GITHUB_OUTPUT - + echo "Status Status - $MATRIX_NAME: $VERSION_CHECK_STATUS" + echo "$MATRIX_NAME=$VERSION_CHECK_STATUS" >> "$GITHUB_OUTPUT" run-version-check-test: name: Run Version Check Test runs-on: ubuntu-22.04 needs: [test-version-check] if: always() + env: + _TS_SEMVER_SUCCESS_STATUS: ${{ needs.test-version-check.outputs.ts_semver_success_status }} + _TS_SEMVER_FAIL_STATUS: ${{ needs.test-version-check.outputs.ts_semver_fail_status }} + _TS_CALVER_SUCCESS_STATUS: ${{ needs.test-version-check.outputs.ts_calver_success_status }} + _TS_CALVER_FAIL_STATUS: ${{ needs.test-version-check.outputs.ts_calver_fail_status }} + _DOTNET_CALVER_SUCCESS_STATUS: ${{ needs.test-version-check.outputs.dotnet_calver_success_status }} + _DOTNET_CALVER_FAIL_STATUS: ${{ needs.test-version-check.outputs.dotnet_calver_fail_status }} + _XAMARIN_CALVER_SUCCESS_STATUS: ${{ needs.test-version-check.outputs.xamarin_calver_success_status }} + _XAMARIN_CALVER_FAIL_STATUS: ${{ needs.test-version-check.outputs.xamarin_calver_fail_status }} steps: - name: Validate Outputs run: | test_outputs=() function assert() { - value=$1 - expected_value=$2 - test_name=$3 + value="$1" + expected_value="$2" + test_name="$3" + if [[ "$value" == "$expected_value" ]]; then echo "${test_name}: pass" test_outputs+=("pass") @@ -106,16 +120,17 @@ jobs: fi } - assert "${{ needs.test-version-check.outputs.ts-semver-success-status }}" "success" "Test TS SemVer Success" - assert "${{ needs.test-version-check.outputs.ts-semver-fail-status }}" "fail" "Test TS SemVer Fail" - assert "${{ needs.test-version-check.outputs.ts-calver-success-status }}" "success" "Test TS CalVer Success" - assert "${{ needs.test-version-check.outputs.ts-calver-fail-status }}" "fail" "Test TS CalVer Fail" - assert "${{ needs.test-version-check.outputs.dotnet-calver-success-status }}" "success" "Test .NET CalVer Success" - assert "${{ needs.test-version-check.outputs.dotnet-calver-fail-status }}" "fail" "Test .NET CalVer Fail" - assert "${{ needs.test-version-check.outputs.xamarin-calver-success-status }}" "success" "Test Xamarin CalVer Success" - assert "${{ needs.test-version-check.outputs.xamarin-calver-fail-status }}" "fail" "Test CalVer Fail" + assert "$_TS_SEMVER_SUCCESS_STATUS" "success" "Test TS SemVer Success" + assert "$_TS_SEMVER_FAIL_STATUS" "fail" "Test TS SemVer Fail" + assert "$_TS_CALVER_SUCCESS_STATUS" "success" "Test TS CalVer Success" + assert "$_TS_CALVER_FAIL_STATUS" "fail" "Test TS CalVer Fail" + assert "$_DOTNET_CALVER_SUCCESS_STATUS" "success" "Test .NET CalVer Success" + assert "$_DOTNET_CALVER_FAIL_STATUS" "fail" "Test .NET CalVer Fail" + assert "$_XAMARIN_CALVER_SUCCESS_STATUS" "success" "Test Xamarin CalVer Success" + assert "$_XAMARIN_CALVER_FAIL_STATUS" "fail" "Test Xamarin CalVer Fail" - if [[ "${test_outputs[@]}" =~ "fail" ]]; then + joined_outputs="${test_outputs[*]}" + if [[ $joined_outputs =~ fail ]]; then exit 1 else exit 0 diff --git a/.github/workflows/test-report-deployment-status-to-slack.yml b/.github/workflows/test-report-deployment-status-to-slack.yml index a5c44c670..fdbcd0349 100644 --- a/.github/workflows/test-report-deployment-status-to-slack.yml +++ b/.github/workflows/test-report-deployment-status-to-slack.yml @@ -1,7 +1,7 @@ name: Test report-deployment-status-to-slack on: pull_request: - paths: + paths: - "report-deployment-status-to-slack/**" - ".github/workflows/test-report-deployment-status-to-slack.yml" @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Start uses: ./report-deployment-status-to-slack @@ -27,7 +29,7 @@ jobs: environment: EU-QA Cloud slack-channel: bre-alerts-test tag: test-workflow-start - event: 'start' + event: "start" commit-sha: $TEST_REPORT_COMMIT_SHA url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} @@ -41,7 +43,7 @@ jobs: environment: US-QA Cloud slack-channel: bre-alerts-test tag: test-workflow-success - event: 'success' + event: "success" commit-sha: $TEST_REPORT_COMMIT_SHA url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} @@ -55,7 +57,7 @@ jobs: environment: US-QA Cloud slack-channel: bre-alerts-test tag: test-workflow-failure - event: 'failure' + event: "failure" commit-sha: $TEST_REPORT_COMMIT_SHA url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} @@ -69,7 +71,7 @@ jobs: environment: EU-QA Cloud slack-channel: bre-alerts-test tag: test-workflow-failure - event: 'no-changes' + event: "no-changes" commit-sha: $TEST_REPORT_COMMIT_SHA url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} @@ -85,6 +87,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: With DB migration true on main uses: ./report-deployment-status-to-slack @@ -93,7 +97,7 @@ jobs: environment: EU-QA Cloud slack-channel: bre-alerts-test tag: main - event: 'success' + event: "success" commit-sha: $TEST_REPORT_COMMIT_SHA db_migration_detected: true url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} @@ -108,7 +112,7 @@ jobs: environment: US-QA Cloud slack-channel: bre-alerts-test tag: main - event: 'failure' + event: "failure" commit-sha: $TEST_REPORT_COMMIT_SHA db_migration_detected: false url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} @@ -123,7 +127,7 @@ jobs: environment: EU-QA Cloud slack-channel: bre-alerts-test tag: test-branch-failure - event: 'failure' + event: "failure" commit-sha: $TEST_REPORT_COMMIT_SHA db_migration_detected: false url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} @@ -138,7 +142,7 @@ jobs: environment: US-QA Cloud slack-channel: bre-alerts-test tag: test-branch-success - event: 'success' + event: "success" commit-sha: $TEST_REPORT_COMMIT_SHA db_migration_detected: true url: https://github.com/bitwarden/gh-actions/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/test-report-upcoming-release-version.yml b/.github/workflows/test-report-upcoming-release-version.yml index c1b893706..dfc929bea 100644 --- a/.github/workflows/test-report-upcoming-release-version.yml +++ b/.github/workflows/test-report-upcoming-release-version.yml @@ -1,7 +1,7 @@ name: Test report-upcoming release version to Slack on: pull_request: - paths: + paths: - "report-upcoming-release-version/**" - ".github/workflows/test-report-upcoming-release-version.yml" @@ -15,6 +15,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Report upcoming release version to Slack uses: ./report-upcoming-release-version diff --git a/.github/workflows/test-version-bump.yml b/.github/workflows/test-version-bump.yml index b21b798a3..8e4475476 100644 --- a/.github/workflows/test-version-bump.yml +++ b/.github/workflows/test-version-bump.yml @@ -24,6 +24,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Bump JSON Test id: test_json @@ -75,12 +77,20 @@ jobs: file_path: "./version-bump/tests/fixtures/Chart.yaml" - name: Validate Outputs + env: + JSON_STATUS: ${{ steps.test_json.outputs.status }} + PLIST_STATUS: ${{ steps.test_plist.outputs.status }} + XML_STATUS: ${{ steps.test_xml.outputs.status }} + PROPS_STATUS: ${{ steps.test_props.outputs.status }} + CSPROJ_STATUS: ${{ steps.test_csproj.outputs.status }} + TOML_STATUS: ${{ steps.test_toml.outputs.status }} + CHART_STATUS: ${{ steps.test_chart.outputs.status }} run: | - echo "${{ steps.test_json.outputs.status }}" - echo "${{ steps.test_plist.outputs.status }}" - echo "${{ steps.test_xml.outputs.status }}" - echo "${{ steps.test_props.outputs.status }}" - echo "${{ steps.test_csproj.outputs.status }}" - echo "${{ steps.test_toml.outputs.status }}" - echo "${{ steps.test_chart.outputs.status }}" + echo "$JSON_STATUS" + echo "$PLIST_STATUS" + echo "$XML_STATUS" + echo "$PROPS_STATUS" + echo "$CSPROJ_STATUS" + echo "$TOML_STATUS" + echo "$CHART_STATUS" git diff diff --git a/.github/workflows/test-version-check.yml b/.github/workflows/test-version-check.yml index 23e582578..e75f1898b 100644 --- a/.github/workflows/test-version-check.yml +++ b/.github/workflows/test-version-check.yml @@ -82,6 +82,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Run version check action id: version-check @@ -94,8 +95,10 @@ jobs: - name: Verify expected failures if: ${{ matrix.type != '' && matrix.should-fail == true }} + env: + _VERSION_CHECK_OUTCOME: ${{ steps.version-check.outcome }} run: | - if [ "${{ steps.version-check.outcome }}" != "failure" ]; then + if [ "$_VERSION_CHECK_OUTCOME" != "failure" ]; then echo "Action was expected to fail but did not." exit 1 fi @@ -110,8 +113,10 @@ jobs: - name: Verify expected failures - default type if: ${{ matrix.type == '' && matrix.should-fail == true }} + env: + _VERSION_CHECK_DEFAULT_TYPE_OUTCOME: ${{ steps.version-check-default-type.outcome }} run: | - if [ "${{ steps.version-check-default-type.outcome }}" != "failure" ]; then + if [ "$_VERSION_CHECK_DEFAULT_TYPE_OUTCOME" != "failure" ]; then echo "Action was expected to fail but did not." exit 1 fi diff --git a/.github/workflows/upload-test-artifacts.yml b/.github/workflows/upload-test-artifacts.yml index 4af994bc5..03ca1fdcc 100644 --- a/.github/workflows/upload-test-artifacts.yml +++ b/.github/workflows/upload-test-artifacts.yml @@ -19,7 +19,7 @@ jobs: - name: Dump run: | mkdir artifact - echo $GITHUB_SHA > artifact/sha + echo "$GITHUB_SHA" > artifact/sha - name: Upload uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 @@ -27,7 +27,6 @@ jobs: name: artifact path: artifact - upload-multiple: name: Upload Multiple runs-on: ubuntu-22.04 @@ -35,8 +34,8 @@ jobs: - name: Dump run: | mkdir artifact1 artifact2 - echo $GITHUB_SHA > artifact1/sha1 - echo $GITHUB_SHA > artifact2/sha2 + echo "$GITHUB_SHA" > artifact1/sha1 + echo "$GITHUB_SHA" > artifact2/sha2 - name: Upload first uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 @@ -50,7 +49,6 @@ jobs: name: artifact2 path: artifact2 - upload-multiple-wildcard-test: name: Upload Multiple Wildcard Test runs-on: ubuntu-22.04 @@ -58,8 +56,8 @@ jobs: - name: Dump run: | mkdir artifact1 artifact2 - echo $GITHUB_SHA > artifact1/sha1 - echo $GITHUB_SHA > artifact2/sha2 + echo "$GITHUB_SHA" > artifact1/sha1 + echo "$GITHUB_SHA" > artifact2/sha2 - name: Upload first uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml index ea8493e53..a36a52c88 100644 --- a/.github/workflows/workflow-linter.yml +++ b/.github/workflows/workflow-linter.yml @@ -22,29 +22,30 @@ jobs: with: repository: ${{ github.repository }} fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }} + persist-credentials: false - name: Check changed files for workflow changes id: changed-workflows run: | - if ${{ github.event_name == 'pull_request' }}; then - changed_files=$(git diff --name-only -r HEAD^1 HEAD | xargs) - else - changed_files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs) - fi + if ${{ github.event_name == 'pull_request' }}; then + changed_files=$(git diff --name-only -r HEAD^1 HEAD | xargs) + else + changed_files=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" | xargs) + fi - count=$(( 0 )) - files_to_lint="" - for file in $changed_files; do - if [[ "$file" == ".github/workflows/"* ]]; then - count=$(( $count + 1 )) - files_to_lint="$files_to_lint $file" - fi - done + count=$(( 0 )) + files_to_lint="" + for file in $changed_files; do + if [[ "$file" == ".github/workflows/"* ]]; then + count=$((count + 1 )) + files_to_lint="$files_to_lint $file" + fi + done - echo "Workflow files changed: $count" - echo "Files to lint: $files_to_lint" - echo "changed_files=$files_to_lint" >> $GITHUB_OUTPUT - echo "changed_files_count=$count" >> $GITHUB_OUTPUT + echo "Workflow files changed: $count" + echo "Files to lint: $files_to_lint" + echo "changed_files=$files_to_lint" >> "$GITHUB_OUTPUT" + echo "changed_files_count=$count" >> "$GITHUB_OUTPUT" - name: Download actionlint configuration if: steps.changed-workflows.outputs.changed_files_count != '0' @@ -70,5 +71,5 @@ jobs: files: ${{ steps.changed-workflows.outputs.changed_files }} if: steps.changed-workflows.outputs.changed_files_count != '0' run: | - echo $files - bwwl lint -f $files + echo "$files" + bwwl lint -f "$files" diff --git a/setup-docker-trust/action.yml b/setup-docker-trust/action.yml index 0cd5a1bc6..3c486bb40 100644 --- a/setup-docker-trust/action.yml +++ b/setup-docker-trust/action.yml @@ -2,26 +2,26 @@ name: "Setup Docker Trust" description: "Configures Docker Trust" inputs: azure-creds: - description: 'Credentials for the Azure Subscription that contains the docker trust secrets. (Deprecated, use AZURE ID inputs instead)' + description: "Credentials for the Azure Subscription that contains the docker trust secrets. (Deprecated, use AZURE ID inputs instead)" required: false default: "" azure-subscription-id: - description: 'The Azure Subscription ID that contains the Key Vault with the specified secrets' + description: "The Azure Subscription ID that contains the Key Vault with the specified secrets" required: false default: "" azure-tenant-id: - description: 'The Azure Tenant ID that contains the Key Vault with the specified secrets' + description: "The Azure Tenant ID that contains the Key Vault with the specified secrets" required: false default: "" azure-client-id: - description: 'The Azure Client ID that contains the Key Vault with the specified secrets' + description: "The Azure Client ID that contains the Key Vault with the specified secrets" required: false default: "" azure-keyvault-name: - description: 'The name of the Key Vault with the specified secrets' + description: "The name of the Key Vault with the specified secrets" outputs: dct-delegate-repo-passphrase: - description: 'DCT Delegate Repository Passphrase' + description: "DCT Delegate Repository Passphrase" value: ${{ steps.get-secrets.outputs.dct-delegate-repo-passphrase }} runs: using: "composite" @@ -29,7 +29,7 @@ runs: - name: Check Runner OS shell: bash run: | - if ["$RUNNER_OS" != "Linux"]; then + if [ "$RUNNER_OS" != "Linux" ]; then echo "[!] This workflow only supports Linux runners" exit 1 fi diff --git a/version-bump/README.md b/version-bump/README.md index 5f379e87c..57e79e679 100644 --- a/version-bump/README.md +++ b/version-bump/README.md @@ -4,6 +4,7 @@ A Github Action that will replace versions in JSON, PLIST, YAML, TOML, and XML f Specifically created for interacting with AndroidManifest, iOS development plists, Helm Charts, Rust Cargo manifests, and Node package JSON files. **Supported file types:** + - JSON: `package.json`, `package-lock.json` (updates `version` and `packages[""].version`) - PLIST: iOS Info.plist files - XML: AndroidManifest.xml, .NET project files (.csproj, .props) @@ -17,7 +18,7 @@ Specifically created for interacting with AndroidManifest, iOS development plist uses: ./version-bump with: version: ${{ inputs.version_number }} - file_path: "./AndroidManifest.xml" + file_path: './AndroidManifest.xml' ``` ## Local Testing diff --git a/version-check/README.md b/version-check/README.md index d1157c3c7..b3916dee9 100644 --- a/version-check/README.md +++ b/version-check/README.md @@ -6,15 +6,18 @@ Given a version and the validation type, will validate that the version is valid If the validation fails, the action run will result in an exit code of 1. ## Inputs + - Version - Version number string - Validation Type - Whether to use SemVer or CalVer (default) validation ## Outputs + None ## Example Snippets Validating SemVer + ``` steps: - name: Validate version - semver @@ -25,6 +28,7 @@ Validating SemVer ``` Validating CalVer + ``` steps: - name: Validate version - calver diff --git a/version-check/action.yml b/version-check/action.yml index b39a23d37..f6b9f0007 100644 --- a/version-check/action.yml +++ b/version-check/action.yml @@ -2,7 +2,7 @@ name: "Version Check" description: "Checks to make sure the version matches the correct format" inputs: version: - description: 'Version string to check' + description: "Version string to check" required: true validation_type: description: 'Type of validation to perform: "semver" or "calver" (default)'