diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e8b6f5e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "06:00" + timezone: "UTC" + open-pull-requests-limit: 1 + groups: + github-actions: + patterns: ["*"] + commit-message: + prefix: "deps" + include: "scope" diff --git a/.github/git-release-ci.sh b/.github/git-release-ci.sh new file mode 100755 index 0000000..9b1d952 --- /dev/null +++ b/.github/git-release-ci.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Creates a GitHub release for a single Flutter SDK package. +# Flutter SDK is a monorepo of independently-versioned packages, so this is +# called once per published package (mindbox, mindbox_android, mindbox_ios, +# mindbox_platform_interface) with that package's tag/title. +# +# Usage: git-release-ci.sh <branch> +tag="${1:?usage: git-release-ci.sh <tag> <title> <branch>}" +title="${2:?usage: git-release-ci.sh <tag> <title> <branch>}" +branch="${3:?usage: git-release-ci.sh <tag> <title> <branch>}" + +notes="Auto-generated release. Check more details at [Mindbox Flutter SDK Documentation](https://developers.mindbox.ru/docs/flutter-sdk)" + +# Idempotent: a re-run of a release must not fail on an already-published tag. +if gh release view "$tag" >/dev/null 2>&1; then + echo "Release $tag already exists — skipping." + exit 0 +fi + +echo "Creating release $tag on branch $branch" +gh release create "$tag" --target "$branch" --title "$title" --notes "$notes" diff --git a/.github/workflows/analyze_and_test.yml b/.github/workflows/analyze_and_test.yml index c8bfa00..090211a 100644 --- a/.github/workflows/analyze_and_test.yml +++ b/.github/workflows/analyze_and_test.yml @@ -16,18 +16,18 @@ on: required: true type: string +permissions: + contents: read + jobs: platform_interface_flutter_test: name: platform_interface running analyze and tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch || github.head_ref }} - - uses: actions/setup-java@v1 - with: - java-version: "12.x" - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: "stable" - name: Add publish_to tag @@ -41,13 +41,10 @@ jobs: name: android_component running analyze and tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch || github.head_ref }} - - uses: actions/setup-java@v1 - with: - java-version: "12.x" - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: "stable" - name: Add publish_to tag @@ -64,13 +61,10 @@ jobs: name: ios_component running analyze and tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch || github.head_ref }} - - uses: actions/setup-java@v1 - with: - java-version: "12.x" - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: "stable" - name: Add publish_to tag @@ -87,13 +81,10 @@ jobs: name: example running analyze runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch || github.head_ref }} - - uses: actions/setup-java@v1 - with: - java-version: "12.x" - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: "stable" @@ -104,13 +95,10 @@ jobs: name: plugin running analyze and tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch || github.head_ref }} - - uses: actions/setup-java@v1 - with: - java-version: "12.x" - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: "stable" diff --git a/.github/workflows/distribute-develop-mission.yml b/.github/workflows/distribute-develop-mission.yml index ad456db..1ada48d 100644 --- a/.github/workflows/distribute-develop-mission.yml +++ b/.github/workflows/distribute-develop-mission.yml @@ -8,10 +8,14 @@ on: types: - closed +permissions: + contents: read + jobs: call-reusable: if: ${{ github.event.pull_request.merged == true }} uses: ./.github/workflows/distribute-reusable.yml with: branch: ${{ github.base_ref }} - secrets: inherit + secrets: + GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} diff --git a/.github/workflows/distribute-manual.yml b/.github/workflows/distribute-manual.yml index 13984e5..49c8ecf 100644 --- a/.github/workflows/distribute-manual.yml +++ b/.github/workflows/distribute-manual.yml @@ -8,10 +8,14 @@ on: required: false default: "" +permissions: + contents: read + jobs: call-reusable: uses: ./.github/workflows/distribute-reusable.yml with: branch: ${{ github.ref_name }} # SDK branch = current branch app_ref: ${{ inputs.app_ref }} # optional override for GitLab ref - secrets: inherit + secrets: + GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} diff --git a/.github/workflows/distribute-release-support-mission.yml b/.github/workflows/distribute-release-support-mission.yml index 06ffa4c..0c22fc8 100644 --- a/.github/workflows/distribute-release-support-mission.yml +++ b/.github/workflows/distribute-release-support-mission.yml @@ -10,10 +10,14 @@ on: - opened - synchronize +permissions: + contents: read + jobs: call-reusable: if: ${{ startsWith(github.event.pull_request.head.ref, 'release/') }} uses: ./.github/workflows/distribute-reusable.yml with: branch: ${{ github.event.pull_request.head.ref }} - secrets: inherit + secrets: + GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} diff --git a/.github/workflows/distribute-reusable.yml b/.github/workflows/distribute-reusable.yml index 98a72fb..4e24c1e 100644 --- a/.github/workflows/distribute-reusable.yml +++ b/.github/workflows/distribute-reusable.yml @@ -14,12 +14,15 @@ on: GITLAB_TRIGGER_TOKEN: required: true +permissions: + contents: read + jobs: trigger: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.branch }} fetch-depth: 3 @@ -29,9 +32,12 @@ jobs: run: | set -euo pipefail commits="$(git log -3 --pretty=format:"%s")" - echo "commits<<EOF" >> "$GITHUB_ENV" - echo "$commits" >> "$GITHUB_ENV" - echo "EOF" >> "$GITHUB_ENV" + delim="EOF_$(openssl rand -hex 8)" + { + echo "commits<<$delim" + echo "$commits" + echo "$delim" + } >> "$GITHUB_ENV" - name: Debug payload that will be sent to GitLab shell: bash diff --git a/.github/workflows/gitleaks-secrets-validate.yml b/.github/workflows/gitleaks-secrets-validate.yml index 0ad5ccb..0946e04 100644 --- a/.github/workflows/gitleaks-secrets-validate.yml +++ b/.github/workflows/gitleaks-secrets-validate.yml @@ -2,18 +2,22 @@ name: Gitleaks Secrets Validate on: pull_request: workflow_dispatch: + +permissions: + contents: read + jobs: scan: name: gitleaks runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Run Gitleaks - uses: gitleaks/gitleaks-action@v2 + uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.MINDBOX_GITLEAKS_LICENSE }} diff --git a/.github/workflows/manual-prepare_release_branch.yml b/.github/workflows/manual-prepare_release_branch.yml index 7666e4d..20c6258 100644 --- a/.github/workflows/manual-prepare_release_branch.yml +++ b/.github/workflows/manual-prepare_release_branch.yml @@ -23,14 +23,18 @@ on: required: true default: 'master' +permissions: + contents: read + jobs: validate-input: name: Validate versions format runs-on: ubuntu-latest steps: - name: Check release_version matches semver + env: + V: ${{ github.event.inputs.release_version }} run: | - V=${{ github.event.inputs.release_version }} echo "Input release_version=$V" if ! [[ "$V" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then echo "❌ release_version must be X.Y.Z or X.Y.Z-rc" @@ -38,8 +42,9 @@ jobs: fi - name: Validate Android SDK version if provided if: ${{ github.event.inputs.android_sdk_version != '' }} + env: + A: ${{ github.event.inputs.android_sdk_version }} run: | - A=${{ github.event.inputs.android_sdk_version }} echo "Input android_sdk_version=$A" if ! [[ "$A" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then echo "❌ android_sdk_version must be X.Y.Z or X.Y.Z-rc" @@ -47,8 +52,9 @@ jobs: fi - name: Validate iOS SDK version if provided if: ${{ github.event.inputs.ios_sdk_version != '' }} + env: + I: ${{ github.event.inputs.ios_sdk_version }} run: | - I=${{ github.event.inputs.ios_sdk_version }} echo "Input ios_sdk_version=$I" if ! [[ "$I" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then echo "❌ ios_sdk_version must be X.Y.Z or X.Y.Z-rc" @@ -61,22 +67,24 @@ jobs: needs: validate-input steps: - name: Checkout minimal repo - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Check source branch + env: + SRC: ${{ github.event.inputs.source_branch }} run: | - SRC=${{ github.event.inputs.source_branch }} echo "Source branch: $SRC" - if ! git ls-remote --heads origin "$SRC" | grep -q "$SRC"; then + if [ -z "$(git ls-remote --heads origin "refs/heads/$SRC")" ]; then echo "❌ source_branch '$SRC' does not exist" exit 1 fi - name: Check target branch + env: + DST: ${{ github.event.inputs.target_branch }} run: | - DST=${{ github.event.inputs.target_branch }} echo "Target branch: $DST" - if ! git ls-remote --heads origin "$DST" | grep -q "$DST"; then + if [ -z "$(git ls-remote --heads origin "refs/heads/$DST")" ]; then echo "❌ target_branch '$DST' does not exist" exit 1 fi @@ -85,11 +93,13 @@ jobs: name: Create release branch & bump versions runs-on: ubuntu-latest needs: validate-branches + permissions: + contents: write outputs: release_branch: ${{ steps.bump.outputs.release_branch }} steps: - name: Checkout source branch - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.inputs.source_branch }} fetch-depth: 0 @@ -101,12 +111,13 @@ jobs: - name: Create branch and update versions id: bump + env: + VERSION: ${{ github.event.inputs.release_version }} + AND_VER: ${{ github.event.inputs.android_sdk_version }} + IO_VER: ${{ github.event.inputs.ios_sdk_version }} + SRC: ${{ github.event.inputs.source_branch }} run: | set -euo pipefail - VERSION="${{ github.event.inputs.release_version }}" - AND_VER="${{ github.event.inputs.android_sdk_version }}" - IO_VER="${{ github.event.inputs.ios_sdk_version }}" - SRC="${{ github.event.inputs.source_branch }}" REL="release/$VERSION" echo "Parameters before fallback: AND_VER=$AND_VER, IO_VER=$IO_VER" @@ -222,10 +233,12 @@ jobs: mindbox_ios/ios/mindbox_ios/Package.swift git commit -m "Bump SDK versions: Flutter=$VERSION, Android=$AND_VER, iOS=$IO_VER" - echo "release_branch=$REL" >> $GITHUB_OUTPUT + echo "release_branch=$REL" >> "$GITHUB_OUTPUT" - name: Push release branch - run: git push --set-upstream origin ${{ steps.bump.outputs.release_branch }} + env: + REL: ${{ steps.bump.outputs.release_branch }} + run: git push --set-upstream origin "$REL" create_pull_request: name: Create Pull Request @@ -238,20 +251,21 @@ jobs: SRC: ${{ needs.bump_and_branch.outputs.release_branch }} DST: ${{ github.event.inputs.target_branch }} REPO: ${{ github.repository }} + RELEASE_VERSION: ${{ github.event.inputs.release_version }} + AND_VER: ${{ github.event.inputs.android_sdk_version }} + IO_VER: ${{ github.event.inputs.ios_sdk_version }} run: | - AND_VER=${{ github.event.inputs.android_sdk_version }} - IO_VER=${{ github.event.inputs.ios_sdk_version }} - [ -z "$AND_VER" ] && AND_VER="${{ github.event.inputs.release_version }}" - [ -z "$IO_VER" ] && IO_VER="${{ github.event.inputs.release_version }}" - + [ -z "$AND_VER" ] && AND_VER="$RELEASE_VERSION" + [ -z "$IO_VER" ] && IO_VER="$RELEASE_VERSION" + BODY=$( - printf 'Automated PR: merge `%s` into `%s`\n\n**Versions:**\n- Flutter SDK: `%s`\n- Android SDK: `%s`\n- iOS SDK: `%s`' \ - "$SRC" "$DST" "${{ github.event.inputs.release_version }}" "$AND_VER" "$IO_VER" + printf "Automated PR: merge \`%s\` into \`%s\`\n\n**Versions:**\n- Flutter SDK: \`%s\`\n- Android SDK: \`%s\`\n- iOS SDK: \`%s\`" \ + "$SRC" "$DST" "$RELEASE_VERSION" "$AND_VER" "$IO_VER" ) gh pr create \ --repo "$REPO" \ --base "$DST" \ --head "$SRC" \ - --title "Release ${{ github.event.inputs.release_version }}" \ + --title "Release $RELEASE_VERSION" \ --body "$BODY" diff --git a/.github/workflows/pr-description-validate.yml b/.github/workflows/pr-description-validate.yml index af3a1f3..8ff6af5 100644 --- a/.github/workflows/pr-description-validate.yml +++ b/.github/workflows/pr-description-validate.yml @@ -3,20 +3,24 @@ name: Validate PR description is not empty on: pull_request: types: [opened, edited, reopened, synchronize] - issue_comment: - types: [created] + +permissions: + contents: read jobs: check-description: runs-on: ubuntu-latest - if: ${{ github.event_name == 'pull_request' || github.event.issue.pull_request }} + permissions: + contents: read + pull-requests: write + issues: write steps: - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Check PR description id: validate_description_step - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | @@ -28,7 +32,7 @@ jobs: core.setOutput('pr_description_check_passed', 'true'); } - name: Find Comment - uses: peter-evans/find-comment@v3 + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 id: fc with: issue-number: ${{ github.event.pull_request.number }} @@ -36,7 +40,7 @@ jobs: - name: Update comment with validation failed statement if: ${{ steps.validate_description_step.outputs.pr_description_check_passed == 'false' }} - uses: peter-evans/create-or-update-comment@v4 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 with: issue-number: ${{ github.event.pull_request.number }} comment-id: ${{ steps.fc.outputs.comment-id }} diff --git a/.github/workflows/publish-dry-run.yml b/.github/workflows/publish-dry-run.yml index ff89255..b8d2d8c 100644 --- a/.github/workflows/publish-dry-run.yml +++ b/.github/workflows/publish-dry-run.yml @@ -6,6 +6,9 @@ on: branches: - 'publish-dry-run/**' +permissions: + contents: read + jobs: dry-run-publish: runs-on: ubuntu-latest @@ -20,14 +23,14 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - uses: subosito/flutter-action@v2 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: stable - name: Dry run publish - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + uses: sakebook/actions-flutter-pub-publisher@7112915a1a834881d4c98ef7af12f3456e5c79c7 # v1.3.1 with: package_directory: ${{ matrix.package }} credential: ${{ secrets.PUB_CREDENTIALS }} diff --git a/.github/workflows/publish-from-master-or-support.yml b/.github/workflows/publish-from-master-or-support.yml index adebf2e..15affe3 100644 --- a/.github/workflows/publish-from-master-or-support.yml +++ b/.github/workflows/publish-from-master-or-support.yml @@ -7,10 +7,17 @@ on: - 'master' - 'support/*' +permissions: + contents: read + jobs: call-reusable: if: ${{ github.event.pull_request.merged == true }} + permissions: + contents: write uses: ./.github/workflows/publish-reusable.yml with: branch: ${{ github.base_ref }} - secrets: inherit + secrets: + PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }} + PAT_FOR_TRIGGERING_BRANCH_PROTECTION: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }} diff --git a/.github/workflows/publish-manual.yml b/.github/workflows/publish-manual.yml index c4f2669..61abf52 100644 --- a/.github/workflows/publish-manual.yml +++ b/.github/workflows/publish-manual.yml @@ -3,20 +3,29 @@ name: SDK publish RC manual on: workflow_dispatch: +permissions: + contents: read + jobs: check-branch: runs-on: ubuntu-latest steps: - name: Check if branch matches pattern + env: + REF_NAME: ${{ github.ref_name }} run: | - if ! echo "${{ github.ref_name }}" | grep -q "release/.*-rc"; then + if ! echo "$REF_NAME" | grep -q "release/.*-rc"; then echo "Branch name must match pattern 'release/*-rc' (e.g. release/2.13.2-rc)" exit 1 fi call-publish-reusable: needs: check-branch + permissions: + contents: write uses: ./.github/workflows/publish-reusable.yml with: branch: ${{ github.ref_name }} - secrets: inherit + secrets: + PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }} + PAT_FOR_TRIGGERING_BRANCH_PROTECTION: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }} diff --git a/.github/workflows/publish-reusable.yml b/.github/workflows/publish-reusable.yml index 62570cf..712cb61 100644 --- a/.github/workflows/publish-reusable.yml +++ b/.github/workflows/publish-reusable.yml @@ -6,6 +6,14 @@ on: branch: required: true type: string + secrets: + PUB_CREDENTIALS: + required: true + PAT_FOR_TRIGGERING_BRANCH_PROTECTION: + required: true + +permissions: + contents: read jobs: analyze_and_test: @@ -13,31 +21,35 @@ jobs: uses: ./.github/workflows/analyze_and_test.yml with: branch: ${{ inputs.branch }} - secrets: inherit platform_interface_publish: needs: [analyze_and_test] timeout-minutes: 4 runs-on: ubuntu-latest name: mindbox_platform_interface publishing + permissions: + contents: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 2 ref: ${{ inputs.branch }} - name: Check package Pubspec id: pubspec + env: + HEAD_SHA: ${{ github.sha }} run: | set +e - git diff-tree --no-commit-id --name-only -r HEAD~1 ${{ github.sha }} | grep 'mindbox_platform_interface/pubspec.yaml' - echo ::set-output name=changed::$? + git diff-tree --no-commit-id --name-only -r HEAD~1 "$HEAD_SHA" | grep 'mindbox_platform_interface/pubspec.yaml' + rc=$? set -e + echo "changed=$rc" >> "$GITHUB_OUTPUT" - name: Extract package version if: steps.pubspec.outputs.changed == 0 run: | cd mindbox_platform_interface - echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> $GITHUB_ENV - - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> "$GITHUB_ENV" + - uses: sakebook/actions-flutter-pub-publisher@7112915a1a834881d4c98ef7af12f3456e5c79c7 # v1.3.1 if: steps.pubspec.outputs.changed == 0 with: package_directory: mindbox_platform_interface @@ -46,16 +58,11 @@ jobs: skip_test: true - name: Create Release if: steps.pubspec.outputs.changed == 0 - id: create_release - uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: mindbox_platform_interface-v${{ env.VERSION }} - release_name: mindbox_platform_interface v${{ env.VERSION }} - draft: false - prerelease: false - + BRANCH: ${{ inputs.branch }} + run: ./.github/git-release-ci.sh "mindbox_platform_interface-v$VERSION" "mindbox_platform_interface v$VERSION" "$BRANCH" + waiting-while-platform-interface-publish: needs: [platform_interface_publish] runs-on: ubuntu-latest @@ -68,6 +75,8 @@ jobs: timeout-minutes: 4 runs-on: ubuntu-latest name: ${{ matrix.package }} publishing + permissions: + contents: write strategy: matrix: package: @@ -76,23 +85,29 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 2 ref: ${{ inputs.branch }} - name: Check package Pubspec id: pubspec + env: + HEAD_SHA: ${{ github.sha }} + PKG: ${{ matrix.package }} run: | set +e - git diff-tree --no-commit-id --name-only -r HEAD~1 ${{ github.sha }} | grep '${{ matrix.package }}/pubspec.yaml' - echo ::set-output name=changed::$? + git diff-tree --no-commit-id --name-only -r HEAD~1 "$HEAD_SHA" | grep "$PKG/pubspec.yaml" + rc=$? set -e + echo "changed=$rc" >> "$GITHUB_OUTPUT" - name: Extract package version if: steps.pubspec.outputs.changed == 0 + env: + PKG: ${{ matrix.package }} run: | - cd ${{ matrix.package }} - echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> $GITHUB_ENV - - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + cd "$PKG" + echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> "$GITHUB_ENV" + - uses: sakebook/actions-flutter-pub-publisher@7112915a1a834881d4c98ef7af12f3456e5c79c7 # v1.3.1 if: steps.pubspec.outputs.changed == 0 with: package_directory: ${{ matrix.package }} @@ -101,16 +116,12 @@ jobs: skip_test: true - name: Create Release if: steps.pubspec.outputs.changed == 0 - id: create_release - uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ matrix.package }}-v${{ env.VERSION }} - release_name: ${{ matrix.package }} v${{ env.VERSION }} - draft: false - prerelease: false - + BRANCH: ${{ inputs.branch }} + PKG: ${{ matrix.package }} + run: ./.github/git-release-ci.sh "$PKG-v$VERSION" "$PKG v$VERSION" "$BRANCH" + waiting-while-native_components_publish: needs: [native_components_publish] runs-on: ubuntu-latest @@ -123,24 +134,29 @@ jobs: timeout-minutes: 4 runs-on: ubuntu-latest name: mindbox publishing + permissions: + contents: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 2 ref: ${{ inputs.branch }} - name: Check package Pubspec id: pubspec + env: + HEAD_SHA: ${{ github.sha }} run: | set +e - git diff-tree --no-commit-id --name-only -r HEAD~1 ${{ github.sha }} | grep 'mindbox/pubspec.yaml' - echo ::set-output name=changed::$? + git diff-tree --no-commit-id --name-only -r HEAD~1 "$HEAD_SHA" | grep 'mindbox/pubspec.yaml' + rc=$? set -e + echo "changed=$rc" >> "$GITHUB_OUTPUT" - name: Extract package version if: steps.pubspec.outputs.changed == 0 run: | cd mindbox - echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> $GITHUB_ENV - - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + echo "VERSION=$(awk '{if ($1 ~ /^version:/) print $2}' pubspec.yaml)" >> "$GITHUB_ENV" + - uses: sakebook/actions-flutter-pub-publisher@7112915a1a834881d4c98ef7af12f3456e5c79c7 # v1.3.1 if: steps.pubspec.outputs.changed == 0 with: package_directory: mindbox @@ -150,27 +166,25 @@ jobs: dry_run: false - name: Create Release if: steps.pubspec.outputs.changed == 0 - id: create_release - uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: mindbox-v${{ env.VERSION }} - release_name: mindbox v${{ env.VERSION }} - draft: false - prerelease: false + BRANCH: ${{ inputs.branch }} + run: ./.github/git-release-ci.sh "mindbox-v$VERSION" "mindbox v$VERSION" "$BRANCH" merge: needs: [plugin_publish] if: | - startsWith(github.head_ref, 'release') && + startsWith(github.head_ref, 'release/') && github.base_ref == 'master' runs-on: ubuntu-latest env: + # gh uses this PAT, not the workflow GITHUB_TOKEN — needed so the merge PR + # re-triggers branch-protection checks. Job-level `permissions:` only scope + # the workflow token, so they don't apply to these gh calls. GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }} steps: - name: Checkout develop branch - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: develop - name: Create Pull Request @@ -178,22 +192,4 @@ jobs: - name: Merge Pull Request run: | pr_number=$(gh pr list --base develop --head master --json number --jq '.[0].number') - gh pr merge $pr_number --merge --auto - - message-to-loop-if-success: - needs: [plugin_publish] - runs-on: ubuntu-latest - steps: - - name: Send message to LOOP - env: - LOOP_NOTIFICATION_WEBHOOK_URL: ${{ secrets.LOOP_NOTIFICATION_WEBHOOK_URL }} - VERSION: ${{ inputs.branch }} - run: | - MESSAGE=$(cat <<EOF - { - "text": "**🤖 Flutter release was successful. Version: ${VERSION}**" - } - EOF) - curl -X POST "$LOOP_NOTIFICATION_WEBHOOK_URL" \ - -H "Content-Type: application/json" \ - -d "$MESSAGE" + gh pr merge "$pr_number" --merge --auto diff --git a/.github/workflows/release-version-check.yml b/.github/workflows/release-version-check.yml index dbc9311..688a0c4 100644 --- a/.github/workflows/release-version-check.yml +++ b/.github/workflows/release-version-check.yml @@ -7,32 +7,35 @@ on: - master - develop +permissions: + contents: read + jobs: check-rc-pattern: runs-on: ubuntu-latest - if: startsWith(github.head_ref, 'release') + if: startsWith(github.head_ref, 'release/') steps: - name: Check RC pattern + env: + HEAD_REF: ${{ github.head_ref }} run: | - if [[ "${{ github.head_ref }}" =~ release/[0-9]+\.[0-9]+\.[0-9]+-rc ]]; then + if [[ "$HEAD_REF" =~ release/[0-9]+\.[0-9]+\.[0-9]+-rc ]]; then echo "Branch name contains release/version-rc pattern. Merging is not allowed. Only stable release should be merge into master" exit 1 fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} check-master-version: needs: check-rc-pattern runs-on: ubuntu-latest - if: github.base_ref == 'master' && startsWith(github.head_ref, 'release') + if: github.base_ref == 'master' && startsWith(github.head_ref, 'release/') steps: - name: Checkout master branch - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master path: master - name: Checkout release branch - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.head_ref }} path: release @@ -40,10 +43,12 @@ jobs: run: | MASTER_VERSION=$(grep 'version:' master/mindbox/pubspec.yaml | awk '{print $2}') RELEASE_VERSION=$(grep 'version:' release/mindbox/pubspec.yaml | awk '{print $2}') - echo "MASTER_VERSION=$MASTER_VERSION" >> $GITHUB_ENV - echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV + { + echo "MASTER_VERSION=$MASTER_VERSION" + echo "RELEASE_VERSION=$RELEASE_VERSION" + } >> "$GITHUB_ENV" - name: Compare versions - uses: jackbilestech/semver-compare@1.0.4 + uses: jackbilestech/semver-compare@b6b063c569b77bea4a0ab627192cbdabf75de3f5 # 1.0.4 with: head: ${{ env.RELEASE_VERSION }} base: ${{ env.MASTER_VERSION }} diff --git a/git-release-branch.sh b/git-release-branch.sh index 20f186a..98aaf59 100755 --- a/git-release-branch.sh +++ b/git-release-branch.sh @@ -1,4 +1,5 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail # Check the current Git branch current_branch=$(git symbolic-ref --short HEAD) @@ -9,7 +10,7 @@ if [[ $current_branch != "develop" && ! $current_branch =~ ^release/[0-9]+\.[0-9 fi # Check if the parameter is provided -read -p "Flutter SDK release version: " version +read -r -p "Flutter SDK release version: " version # Check if the version number matches the semver format if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then @@ -19,8 +20,8 @@ fi # Create a branch with the version name branch_name="release/$version" -git branch $branch_name -git checkout $branch_name +git branch "$branch_name" +git checkout "$branch_name" echo "Branch $branch_name has been created." @@ -51,7 +52,7 @@ git add $ios_yaml git add $android_yaml git add $common_yaml -read -p "Android SDK version: " android_sdk_version +read -r -p "Android SDK version: " android_sdk_version # Check if the version number matches the semver format if ! [[ $android_sdk_version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then @@ -59,7 +60,7 @@ if ! [[ $android_sdk_version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then exit 1 fi -read -p "iOS SDK version: " ios_sdk_version +read -r -p "iOS SDK version: " ios_sdk_version # Check if the version number matches the semver format if ! [[ $ios_sdk_version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then diff --git a/version-update.sh b/version-update.sh index c385af4..59440ef 100644 --- a/version-update.sh +++ b/version-update.sh @@ -1,3 +1,4 @@ -#!/bin/bash -VERSION=$1 -sed -i -e "s|mindbox: ^[0-9].[0-9].[0-9]|mindbox: ^${VERSION}|" README.md \ No newline at end of file +#!/usr/bin/env bash +set -euo pipefail +VERSION="${1:?usage: version-update.sh <version>}" +sed -i -e "s|mindbox: ^[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}|mindbox: ^${VERSION}|" README.md \ No newline at end of file