diff --git a/.dockerignore b/.dockerignore index 949de17e5b..146e253a30 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,4 +16,6 @@ ecosystem/**/package-lock.json .git/ .idea/ .vscode/ -.storage/ \ No newline at end of file +.storage/ + +Dockerfile \ No newline at end of file diff --git a/.github/scripts/create-release.sh b/.github/scripts/create-release.sh new file mode 100644 index 0000000000..e7e135e899 --- /dev/null +++ b/.github/scripts/create-release.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -ue + +SEMVER_REGEX='^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' + +REL_VERSION=`echo $1 | sed -r 's/^[vV]?([0-9].+)$/\1/'` + +if [ `echo $REL_VERSION | pcre2grep "$SEMVER_REGEX"` ]; then + echo "$REL_VERSION is a valid semantic version." +else + echo "$REL_VERSION is not a valid semantic version." + exit 1 +fi + +MAJOR_MINOR_VERSION=`echo $REL_VERSION | cut -d. -f1,2` +RELEASE_BRANCH="release-$MAJOR_MINOR_VERSION" +RELEASE_TAG="v$REL_VERSION" + +if [ `git rev-parse --verify origin/$RELEASE_BRANCH 2>/dev/null` ]; then + echo "$RELEASE_BRANCH branch already exists, checking it out ..." + git checkout $RELEASE_BRANCH +else + echo "$RELEASE_BRANCH does not exist, creating ..." + git checkout -b $RELEASE_BRANCH + git push origin $RELEASE_BRANCH +fi +echo "$RELEASE_BRANCH branch is ready." + +if [ `git rev-parse --verify $RELEASE_TAG 2>/dev/null` ]; then + echo "$RELEASE_TAG tag already exists, aborting ..." + exit 2 +fi + +echo "Tagging $RELEASE_TAG ..." +git tag $RELEASE_TAG +echo "$RELEASE_TAG is tagged." + +echo "Pushing $RELEASE_TAG tag ..." +git push origin $RELEASE_TAG +echo "$RELEASE_TAG tag is pushed." \ No newline at end of file diff --git a/.github/workflows/create_release.yaml b/.github/workflows/create_release.yaml new file mode 100644 index 0000000000..5511d9639e --- /dev/null +++ b/.github/workflows/create_release.yaml @@ -0,0 +1,32 @@ +name: Create a release + +on: + workflow_dispatch: + inputs: + rel_version: + description: 'Release version (examples: v1.3.0-rc.1, v1.3.0)' + required: true + type: string + +jobs: + create-release: + name: Creates release branch and tag + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install required packages + run: | + sudo apt-get update + sudo apt-get install pcre2-utils + - name: Create release branch and tag + env: + GITHUB_TOKEN: ${{ secrets.LAVANET_BOT_TOKEN }} + run: | + git config user.email "bot@lavanet.xyz" + git config user.name "LavaNet Bot" + # Update origin with token + git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git + ./.github/scripts/create-release.sh ${{ inputs.rel_version }} \ No newline at end of file diff --git a/.github/workflows/lava.yml b/.github/workflows/lava.yml new file mode 100644 index 0000000000..e95435cd5d --- /dev/null +++ b/.github/workflows/lava.yml @@ -0,0 +1,71 @@ +name: Lava + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + ci: + strategy: + matrix: + binary: [lavad, lavap, lavavisor] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.20.5 + go-version-file: go.mod + cache-dependency-path: go.sum + + - name: Run GoReleaser + id: releaser + uses: goreleaser/goreleaser-action@v5 + with: + version: latest + args: build --single-target --snapshot --clean + workdir: cmd/${{ matrix.binary }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.binary }}-${{ fromJson(steps.releaser.outputs.metadata).tag }}-${{ fromJson(steps.releaser.outputs.artifacts)[0].goos }}-${{ fromJson(steps.releaser.outputs.artifacts)[0].goarch }} + path: cmd/${{ matrix.binary }}/${{ fromJson(steps.releaser.outputs.artifacts)[0].path }} + + # - name: Docker meta + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: | + # lava/${{ matrix.binary }} + # ghcr.io/lavanet/${{ matrix.binary }} + # tags: | + # type=raw,value=latest,enable={{is_default_branch}} + # type=schedule + # type=ref,event=branch + # type=ref,event=pr + # type=semver,pattern={{version}} + # type=semver,pattern={{major}}.{{minor}} + # type=semver,pattern={{major}} + # type=sha + # - name: Set up QEMU + # uses: docker/setup-qemu-action@v3 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v3 + # - name: Build and push + # uses: docker/build-push-action@v5 + # with: + # context: . + # push: ${{ github.event_name != 'pull_request' }} + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} + \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/lint.yml similarity index 55% rename from .github/workflows/main.yml rename to .github/workflows/lint.yml index abf10f1967..932e04cecb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/lint.yml @@ -5,20 +5,22 @@ on: branches: - main pull_request: + branches: + - main jobs: lint: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.20.5 - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: - args: --print-issued-lines --config .golangci.yml -v + args: --print-issued-lines --config .golangci.yml -v \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3999fb985a..6f340f036c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,9 @@ -name: 'Release' +name: Publish Lava Release on: - release: - types: [created, edited, prereleased] + push: + tags: + - 'v*' permissions: contents: write @@ -10,133 +11,129 @@ permissions: jobs: release: name: 'release' - runs-on: ubuntu-20.04 - timeout-minutes: 10 - environment: default - defaults: - run: - shell: bash + strategy: + matrix: + binary: [lavad, lavap, lavavisor] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Configure Go - uses: actions/setup-go@v3 + - name: Checkout code + uses: actions/checkout@v4 with: - go-version: 1.20.5 - check-latest: true - cache: true + fetch-depth: 0 - - name: Set Environment Variable + - name: Fetch all tags run: | - echo "LAVA_BUILD_OPTIONS=\"release\"" >> $GITHUB_ENV + set -e + git fetch --force --tags - - name: Build - run: | - make build-all + - name: Configure Go + uses: actions/setup-go@v5 + with: + go-version: 1.20.5 + go-version-file: go.mod + cache-dependency-path: go.sum - - name: Test build - continue-on-error: true - run: | - response=$(build/lavad status --node http://public-rpc.lavanet.xyz:80/rpc/ | jq '.NodeInfo') - if [ -z "${response}" ]; then - echo "The binary fails to connect to a node." - exit 1 - else - echo $response - echo "The binary is working as expected." - fi - - - name: Check for existing assests - id: existing_asset - run: | - if [ "${{ github.event.release.assets[0].name }}" = "lavad" ]; then - echo "URL=${{ github.event.release.assets[0].id }}" >> $GITHUB_OUTPUT - echo "URL=${{ github.event.release.assets[0].url }}" >> $GITHUB_OUTPUT - echo "CHECK=true" >> $GITHUB_OUTPUT - else - echo "CHECK=false" >> $GITHUB_OUTPUT - fi - - - name: Upload build to release - run: | - upload_binary () { - echo "Uploading binary to: $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavad/g')" - curl \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Content-Type: $(file -b --mime-type build/lavad)" \ - --data-binary @build/lavad \ - $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavad-${{ github.event.release.tag_name }}-linux-amd64/g') - - curl \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Content-Type: $(file -b --mime-type build/lavap)" \ - --data-binary @build/lavap \ - $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavap-${{ github.event.release.tag_name }}-linux-amd64/g') - - curl \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Content-Type: $(file -b --mime-type build/lavavisor)" \ - --data-binary @build/lavavisor \ - $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavavisor-${{ github.event.release.tag_name }}-linux-amd64/g') - } - - delete_binary(){ - echo "Deleting existing binary" - curl \ - -X DELETE \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - ${{ steps.existing_asset.outputs.URL }} - } - - if ${{ steps.existing_asset.outputs.CHECK }}; then - delete_binary - upload_binary - else - upload_binary - fi - - - name: Check for existing Checksum - id: existing_checksum - run: | - #Get Checksum of new build - export CHECKSUM=$(sha256sum build/lavad | cut -d " " -f1) - - #Get the existing body - existing_body=$(curl \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Content-Type: $(file -b --mime-type build/lavad)" \ - ${{ github.event.release.url }} | jq '.body') - - if [[ $existing_body == *"$CHECKSUM"* ]]; then - echo "CHECK=true" >> $GITHUB_OUTPUT - echo "Checksum hasn't changed." - else - echo "CHECK=false" >> $GITHUB_OUTPUT - cat <> /tmp/body - $(echo $existing_body | sed '$s/.$//')\r\nChecksum $CHECKSUM" - EOF - echo -E "NEW_BODY=$(cat /tmp/body)" >> $GITHUB_OUTPUT - fi - - - name: Append Binary Checksum - uses: actions/github-script@v6 - if: ${{ steps.existing_checksum.outputs.CHECK }} == 'false' + - name: Run GoReleaser + id: releaser + uses: goreleaser/goreleaser-action@v5 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { data } = await github.rest.repos.updateRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: context.payload.release.id, - body: ${{ steps.existing_checksum.outputs.NEW_BODY }} - }); + version: latest + args: release --clean --timeout 90m + workdir: cmd/${{ matrix.binary }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # - name: Check for existing assests + # id: existing_asset + # run: | + # if [ "${{ github.event.release.assets[0].name }}" = "lavad" ]; then + # echo "URL=${{ github.event.release.assets[0].id }}" >> $GITHUB_OUTPUT + # echo "URL=${{ github.event.release.assets[0].url }}" >> $GITHUB_OUTPUT + # echo "CHECK=true" >> $GITHUB_OUTPUT + # else + # echo "CHECK=false" >> $GITHUB_OUTPUT + # fi + + # - name: Upload build to release + # run: | + # upload_binary () { + # echo "Uploading binary to: $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavad/g')" + # curl \ + # -X POST \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + # -H "Content-Type: $(file -b --mime-type build/lavad)" \ + # --data-binary @build/lavad \ + # $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavad-${{ github.event.release.tag_name }}-linux-amd64/g') + + # curl \ + # -X POST \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + # -H "Content-Type: $(file -b --mime-type build/lavap)" \ + # --data-binary @build/lavap \ + # $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavap-${{ github.event.release.tag_name }}-linux-amd64/g') + + # curl \ + # -X POST \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + # -H "Content-Type: $(file -b --mime-type build/lavavisor)" \ + # --data-binary @build/lavavisor \ + # $(echo '${{ github.event.release.upload_url }}' | sed 's/{?name,label}/?name=lavavisor-${{ github.event.release.tag_name }}-linux-amd64/g') + # } + + # delete_binary(){ + # echo "Deleting existing binary" + # curl \ + # -X DELETE \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + # ${{ steps.existing_asset.outputs.URL }} + # } + + # if ${{ steps.existing_asset.outputs.CHECK }}; then + # delete_binary + # upload_binary + # else + # upload_binary + # fi + + # - name: Check for existing Checksum + # id: existing_checksum + # run: | + # #Get Checksum of new build + # export CHECKSUM=$(sha256sum build/lavad | cut -d " " -f1) + + # #Get the existing body + # existing_body=$(curl \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + # -H "Content-Type: $(file -b --mime-type build/lavad)" \ + # ${{ github.event.release.url }} | jq '.body') + + # if [[ $existing_body == *"$CHECKSUM"* ]]; then + # echo "CHECK=true" >> $GITHUB_OUTPUT + # echo "Checksum hasn't changed." + # else + # echo "CHECK=false" >> $GITHUB_OUTPUT + # cat <> /tmp/body + # $(echo $existing_body | sed '$s/.$//')\r\nChecksum $CHECKSUM" + # EOF + # echo -E "NEW_BODY=$(cat /tmp/body)" >> $GITHUB_OUTPUT + # fi + + # - name: Append Binary Checksum + # uses: actions/github-script@v6 + # if: ${{ steps.existing_checksum.outputs.CHECK }} == 'false' + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} + # script: | + # const { data } = await github.rest.repos.updateRelease({ + # owner: context.repo.owner, + # repo: context.repo.repo, + # release_id: context.payload.release.id, + # body: ${{ steps.existing_checksum.outputs.NEW_BODY }} + # }); \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2719be8dfd..701735eb0f 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,5 @@ testutil/e2e/sdk/tests/node_modules.json config/health_examples/health_template_gen.yml # Yarn .yarn/ + +**/dist/ \ No newline at end of file diff --git a/cmd/lavad/.goreleaser.yaml b/cmd/lavad/.goreleaser.yaml new file mode 100644 index 0000000000..a15276f706 --- /dev/null +++ b/cmd/lavad/.goreleaser.yaml @@ -0,0 +1,82 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com + +# The lines bellow are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj +project_name: lavad +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... + +builds: + - id: lavad + env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + ignore: + - goos: darwin + goarch: s390x + - goos: darwin + goarch: ppc64le + - goos: windows + goarch: s390x + - goos: windows + goarch: ppc64le + - goos: windows + goarch: arm64 + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt' + algorithm: sha256 + +changelog: + use: + github + sort: asc + abbrev: 0 + groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax. + - title: 'Features' + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 100 + - title: 'Bug fixes' + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 200 + - title: 'Documentation' + regexp: '^.*?docs(\([[:word:]]+\))??!?:.+$' + order: 300 + - title: 'Dependency updates' + regexp: '^.*?(feat|fix|chore)\(deps?.+\)!?:.+$' + order: 400 + - title: 'Other work' + order: 999 + filters: + exclude: + - '^test:' + - '^.*?Bump(\([[:word:]]+\))?.+$' + - '^.*?[Bot](\([[:word:]]+\))?.+$' diff --git a/cmd/lavap/.goreleaser.yaml b/cmd/lavap/.goreleaser.yaml new file mode 100644 index 0000000000..bda7397982 --- /dev/null +++ b/cmd/lavap/.goreleaser.yaml @@ -0,0 +1,82 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com + +# The lines bellow are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj +project_name: lavap +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... + +builds: + - id: lavap + env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + ignore: + - goos: darwin + goarch: s390x + - goos: darwin + goarch: ppc64le + - goos: windows + goarch: s390x + - goos: windows + goarch: ppc64le + - goos: windows + goarch: arm64 + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt' + algorithm: sha256 + +changelog: + use: + github + sort: asc + abbrev: 0 + groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax. + - title: 'Features' + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 100 + - title: 'Bug fixes' + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 200 + - title: 'Documentation' + regexp: '^.*?docs(\([[:word:]]+\))??!?:.+$' + order: 300 + - title: 'Dependency updates' + regexp: '^.*?(feat|fix|chore)\(deps?.+\)!?:.+$' + order: 400 + - title: 'Other work' + order: 999 + filters: + exclude: + - '^test:' + - '^.*?Bump(\([[:word:]]+\))?.+$' + - '^.*?[Bot](\([[:word:]]+\))?.+$' diff --git a/cmd/lavavisor/.goreleaser.yaml b/cmd/lavavisor/.goreleaser.yaml new file mode 100644 index 0000000000..64e4bbdd72 --- /dev/null +++ b/cmd/lavavisor/.goreleaser.yaml @@ -0,0 +1,82 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com + +# The lines bellow are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj +project_name: lavavisor +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... + +builds: + - id: lavavisor + env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + ignore: + - goos: darwin + goarch: s390x + - goos: darwin + goarch: ppc64le + - goos: windows + goarch: s390x + - goos: windows + goarch: ppc64le + - goos: windows + goarch: arm64 + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt' + algorithm: sha256 + +changelog: + use: + github + sort: asc + abbrev: 0 + groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax. + - title: 'Features' + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 100 + - title: 'Bug fixes' + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 200 + - title: 'Documentation' + regexp: '^.*?docs(\([[:word:]]+\))??!?:.+$' + order: 300 + - title: 'Dependency updates' + regexp: '^.*?(feat|fix|chore)\(deps?.+\)!?:.+$' + order: 400 + - title: 'Other work' + order: 999 + filters: + exclude: + - '^test:' + - '^.*?Bump(\([[:word:]]+\))?.+$' + - '^.*?[Bot](\([[:word:]]+\))?.+$' \ No newline at end of file