Initial commit
Based on JMusicBot by jagrosh (https://github.com/jagrosh/MusicBot), via the maintained fork by arif-banai (https://github.com/arif-banai/MusicBot). See NOTICE for attribution. Licensed under Apache 2.0. YouTube-side changes had broken playback entirely. Fixes: - Apply the remote signature cipher independently of OAuth. Deciphering and authentication are unrelated, but the cipher was only configured when OAuth was enabled, so the default install fell back to the bundled extractor and failed with "Must find sig function from script: /s/player/<id>/...". Now always applied, and configurable via playback.youtube.remoteCipher.url. - Add the ANDROID client and order the client list by reliability. ANDROID is currently the only client YouTube reliably streams to anonymously. WEB moves last, as YouTube answers it with SABR-only responses carrying no playable format ("No supported audio streams available, available types:"). - Detect sign-in failures across the whole exception graph. The existing hint could never fire: it matched the aggregate AllClientsFailedException message rather than the per-client reasons, and compared against an ASCII apostrophe while YouTube sends U+2019. - Track youtube-source past 1.18.2, which predates the TV client User-Agent fix and the contentLength recovery fix. Measured on previously failing tracks: 5/5 playing, stable across repeat runs (was 1/5). No OAuth required. Adds 17 tests; 676 unit + 48 integration pass.
This commit is contained in:
commit
0941987234
295 files changed
+58207
No files matched your search
@@ -0,0 +1,63 @@
|
||||
name: Build and Test
|
||||
|
||||
# Build and test on PRs and master pushes
|
||||
# This workflow does NOT publish Docker images - that's handled by docker-publish.yml
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master # PRs targeting trunk
|
||||
push:
|
||||
branches:
|
||||
- master # Direct pushes to master
|
||||
paths-ignore:
|
||||
- '.github/**' # Ignore GitHub config changes (workflows, actions, templates, etc.)
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
- 'CNAME'
|
||||
- 'docs/**'
|
||||
- '*.example.yml'
|
||||
- '*.example.yaml'
|
||||
- '.circleci/**' # If not using CircleCI, ignore its config
|
||||
|
||||
# Cancel in-progress runs for the same workflow and branch
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read # Only need to checkout repository
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Java Environment
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: 'temurin'
|
||||
cache: maven
|
||||
|
||||
- name: Build and Test with Coverage
|
||||
run: |
|
||||
COMMIT_TIME=$(git log -1 --format=%cI)
|
||||
mvn --batch-mode verify -Pcoverage -Dproject.build.outputTimestamp=$COMMIT_TIME
|
||||
|
||||
- name: Upload Coverage to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
report_type: coverage
|
||||
files: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results to Codecov
|
||||
if: ${{ !cancelled() }}
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
report_type: test_results
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@@ -0,0 +1,120 @@
|
||||
name: Publish Docker Image
|
||||
|
||||
# Docker publishing workflow - gated by successful build-and-test completion
|
||||
# This ensures images are only published after tests pass on master
|
||||
on:
|
||||
# Triggered after successful build-and-test on master
|
||||
# Note: The branches filter checks workflow_run.head_branch, which is the source branch
|
||||
# of the triggering workflow. For PRs targeting master, head_branch is the PR source
|
||||
# branch (not master), so this filter already excludes PR-triggered builds. Only direct
|
||||
# pushes to master will have head_branch == 'master' and trigger this workflow.
|
||||
workflow_run:
|
||||
workflows: ["Build and Test"]
|
||||
types:
|
||||
- completed
|
||||
branches:
|
||||
- master
|
||||
# Also trigger on version tags (v*) for releases
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
# Cancel in-progress runs for the same workflow and ref
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: arif-banai/musicbot
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
# Only run if the triggering workflow succeeded (for workflow_run events)
|
||||
# For tag pushes, always run
|
||||
if: |
|
||||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') ||
|
||||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # Required for pushing to GHCR
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
# For workflow_run events, checkout the commit that triggered the original workflow
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
|
||||
fetch-depth: 0 # Full history needed for git commands
|
||||
|
||||
- name: Extract metadata
|
||||
id: metadata
|
||||
run: |
|
||||
# Extract project version from pom.xml
|
||||
POM_VERSION=$(grep -m 1 '<version>' pom.xml | sed 's/.*<version>\([^<]*\)<\/version>.*/\1/' | tr -d ' ')
|
||||
SHA_SHORT=$(git rev-parse --short HEAD)
|
||||
TIMESTAMP=$(git log -1 --format=%cI)
|
||||
|
||||
# Determine if this is a tag build or master branch build
|
||||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
|
||||
# For tag builds, use the git tag version (strip 'v' prefix)
|
||||
VERSION="${GITHUB_REF#refs/tags/v}"
|
||||
IS_TAG_BUILD="true"
|
||||
else
|
||||
# For master builds, use pom.xml version
|
||||
VERSION="$POM_VERSION"
|
||||
IS_TAG_BUILD="false"
|
||||
fi
|
||||
|
||||
# Check if version is a SNAPSHOT
|
||||
if [[ "$VERSION" =~ -SNAPSHOT$ ]]; then
|
||||
IS_SNAPSHOT="true"
|
||||
else
|
||||
IS_SNAPSHOT="false"
|
||||
fi
|
||||
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "pom_version=$POM_VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "sha=$SHA_SHORT" >> "$GITHUB_OUTPUT"
|
||||
echo "timestamp=$TIMESTAMP" >> "$GITHUB_OUTPUT"
|
||||
echo "is_tag_build=$IS_TAG_BUILD" >> "$GITHUB_OUTPUT"
|
||||
echo "is_snapshot=$IS_SNAPSHOT" >> "$GITHUB_OUTPUT"
|
||||
echo "Extracted version: $VERSION (pom: $POM_VERSION), SHA: $SHA_SHORT, is_tag: $IS_TAG_BUILD, is_snapshot: $IS_SNAPSHOT"
|
||||
|
||||
- name: Generate Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
env:
|
||||
# For multi-arch images, annotations must be attached to the image index
|
||||
# GitHub Packages reads annotations from the index level for multi-arch images
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
# Tag rules:
|
||||
# - For tag builds: version tag (from git tag) + sha tag
|
||||
# - For master builds: latest + sha + version (if not SNAPSHOT)
|
||||
tags: |
|
||||
type=raw,value=${{ steps.metadata.outputs.version }},enable=${{ steps.metadata.outputs.is_tag_build == 'true' }}
|
||||
type=raw,value=latest,enable=${{ steps.metadata.outputs.is_tag_build == 'false' }}
|
||||
type=raw,value=${{ steps.metadata.outputs.version }},enable=${{ steps.metadata.outputs.is_tag_build == 'false' && steps.metadata.outputs.is_snapshot == 'false' }}
|
||||
type=raw,value=sha-${{ steps.metadata.outputs.sha }}
|
||||
# Labels are automatically generated from git context by metadata-action
|
||||
# No need to specify them - metadata-action will create standard OCI labels
|
||||
|
||||
- name: Build and push Docker image
|
||||
id: build
|
||||
uses: ./.github/actions/docker-build
|
||||
with:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
annotations: ${{ steps.meta.outputs.annotations }}
|
||||
timestamp: ${{ steps.metadata.outputs.timestamp }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
image-name: ${{ env.IMAGE_NAME }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Image digest
|
||||
run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}"
|
||||
@@ -0,0 +1,153 @@
|
||||
name: Make Release
|
||||
|
||||
# Manual workflow to create a GitHub release
|
||||
# This sets the version, builds the JAR, and creates a release with tag
|
||||
# The tag will trigger docker-publish.yml to build and push the Docker image
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_number:
|
||||
description: 'Version Number (e.g., 0.6.3)'
|
||||
required: true
|
||||
type: string
|
||||
info:
|
||||
description: 'Description of this Release'
|
||||
required: true
|
||||
type: string
|
||||
is_prerelease:
|
||||
description: 'Mark this as a pre-release (for testing)'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
ref:
|
||||
description: 'Branch, tag, or SHA to build from (defaults to the branch this workflow is run from)'
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
# Prevent concurrent releases
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build_jar:
|
||||
name: Build JAR
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: write # Required to push version commit
|
||||
outputs:
|
||||
release_sha: ${{ steps.set-release-sha.outputs.sha }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.inputs.ref || github.ref }}
|
||||
fetch-depth: 0 # Full history needed for git commands
|
||||
|
||||
- name: Validate branch for regular releases
|
||||
if: ${{ github.event.inputs.is_prerelease != 'true' }}
|
||||
run: |
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$BRANCH" != "master" ]; then
|
||||
echo "❌ Error: Regular releases can only be created from the 'master' branch."
|
||||
echo " Current branch: $BRANCH"
|
||||
echo " To create a pre-release from this branch, check the 'Mark this as a pre-release' option."
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Branch validation passed: $BRANCH"
|
||||
|
||||
- name: Set up Java Environment
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: 'temurin'
|
||||
cache: maven
|
||||
|
||||
- name: Get initial SHA (for pre-releases)
|
||||
id: get-initial-sha
|
||||
if: ${{ github.event.inputs.is_prerelease == 'true' }}
|
||||
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set Version
|
||||
run: |
|
||||
mvn -B versions:set -DnewVersion=${{ github.event.inputs.version_number }}
|
||||
mvn -B versions:commit
|
||||
|
||||
- name: Commit version bump
|
||||
if: ${{ github.event.inputs.is_prerelease != 'true' }}
|
||||
id: commit-version
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Stage whatever the version plugin changed
|
||||
git add pom.xml
|
||||
|
||||
# If nothing is staged, don't fail the workflow
|
||||
if git diff --cached --quiet; then
|
||||
echo "No version changes to commit (pom.xml already at ${{ github.event.inputs.version_number }})."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git commit -m "chore: bump version to ${{ github.event.inputs.version_number }}"
|
||||
git push
|
||||
|
||||
|
||||
- name: Set release SHA output
|
||||
id: set-release-sha
|
||||
run: |
|
||||
if [ "${{ github.event.inputs.is_prerelease }}" == "true" ]; then
|
||||
echo "sha=${{ steps.get-initial-sha.outputs.sha }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Build with Maven
|
||||
run: |
|
||||
COMMIT_TIME=$(git log -1 --format=%cI)
|
||||
mvn --batch-mode verify -Dproject.build.outputTimestamp=$COMMIT_TIME
|
||||
|
||||
- name: Rename JAR
|
||||
run: mv target/*-All.jar JMusicBot-${{ github.event.inputs.version_number }}.jar
|
||||
|
||||
- name: Upload JAR artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: jar
|
||||
path: JMusicBot-${{ github.event.inputs.version_number }}.jar
|
||||
if-no-files-found: error
|
||||
|
||||
create_release:
|
||||
name: Create GitHub Release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: build_jar
|
||||
permissions:
|
||||
contents: write # Required to create releases and tags
|
||||
steps:
|
||||
- name: Download JAR artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: jar
|
||||
path: .
|
||||
|
||||
- name: Create Release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: v${{ github.event.inputs.version_number }}
|
||||
commit: ${{ needs.build_jar.outputs.release_sha }}
|
||||
name: v${{ github.event.inputs.version_number }}
|
||||
draft: true
|
||||
prerelease: ${{ github.event.inputs.is_prerelease }}
|
||||
artifacts: "*.jar"
|
||||
body: |
|
||||
${{ github.event.inputs.info }}
|
||||
|
||||
---
|
||||
### Setup
|
||||
https://jmusicbot.com/setup
|
||||
https://jmusicbot.com/config
|
||||
# Download: [JMusicBot-${{ github.event.inputs.version_number }}.jar](https://github.com/arif-banai/MusicBot/releases/download/v${{ github.event.inputs.version_number }}/JMusicBot-${{ github.event.inputs.version_number }}.jar)
|
||||
@@ -0,0 +1,131 @@
|
||||
name: Publish Preview Image
|
||||
|
||||
# Optional workflow for manually publishing preview Docker images from any branch/tag/SHA
|
||||
# This is separate from the main CI/CD pipeline and allows explicit preview builds
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'Git ref to build (branch name, tag, or SHA)'
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
description: 'Optional tag suffix override (if empty, derived from ref)'
|
||||
required: false
|
||||
type: string
|
||||
run_tests:
|
||||
description: 'Run Maven tests before building Docker image'
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
# Cancel in-progress runs for the same workflow and ref
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.inputs.ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: arif-banai/musicbot
|
||||
|
||||
jobs:
|
||||
publish-preview:
|
||||
name: Publish Preview Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # Required for pushing to GHCR
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
fetch-depth: 0 # Full history needed for git commands
|
||||
|
||||
- name: Extract metadata
|
||||
id: metadata
|
||||
run: |
|
||||
# Extract project version from pom.xml
|
||||
VERSION=$(grep -m 1 '<version>' pom.xml | sed 's/.*<version>\([^<]*\)<\/version>.*/\1/' | tr -d ' ')
|
||||
SHA_SHORT=$(git rev-parse --short HEAD)
|
||||
TIMESTAMP=$(git log -1 --format=%cI)
|
||||
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "sha=$SHA_SHORT" >> "$GITHUB_OUTPUT"
|
||||
echo "timestamp=$TIMESTAMP" >> "$GITHUB_OUTPUT"
|
||||
echo "Extracted version: $VERSION, SHA: $SHA_SHORT"
|
||||
|
||||
- name: Set up Java Environment
|
||||
# Run if run_tests is true (default) or explicitly set to true
|
||||
if: ${{ github.event.inputs.run_tests != 'false' }}
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: 'temurin'
|
||||
cache: maven
|
||||
|
||||
- name: Run Maven tests
|
||||
# Run if run_tests is true (default) or explicitly set to true
|
||||
if: ${{ github.event.inputs.run_tests != 'false' }}
|
||||
run: |
|
||||
COMMIT_TIME=$(git log -1 --format=%cI)
|
||||
mvn --batch-mode verify -Pdocker -Dproject.build.outputTimestamp=$COMMIT_TIME
|
||||
|
||||
- name: Sanitize tag suffix
|
||||
id: sanitize
|
||||
run: |
|
||||
# Determine the tag suffix: use input.tag if provided, otherwise derive from ref
|
||||
if [[ -n "${{ github.event.inputs.tag }}" ]]; then
|
||||
TAG_SUFFIX="${{ github.event.inputs.tag }}"
|
||||
else
|
||||
# Derive from ref: strip refs/heads/, refs/tags/, refs/ prefixes
|
||||
REF="${{ github.event.inputs.ref }}"
|
||||
REF="${REF#refs/heads/}"
|
||||
REF="${REF#refs/tags/}"
|
||||
REF="${REF#refs/}"
|
||||
TAG_SUFFIX="$REF"
|
||||
fi
|
||||
|
||||
# Sanitize: lowercase, replace '/' with '-', strip invalid chars to [a-z0-9._-]
|
||||
# Truncate to 50 characters to avoid tag length issues
|
||||
SANITIZED=$(echo "$TAG_SUFFIX" | tr '[:upper:]' '[:lower:]' | tr '/' '-' | tr -cd '[:alnum:]._-' | cut -c1-50)
|
||||
|
||||
echo "suffix=$SANITIZED" >> "$GITHUB_OUTPUT"
|
||||
echo "Sanitized tag suffix: $SANITIZED"
|
||||
|
||||
- name: Generate Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
env:
|
||||
# For multi-arch images, annotations must be attached to the image index
|
||||
# GitHub Packages reads annotations from the index level for multi-arch images
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
# Tag rules for preview images:
|
||||
# - preview-<sanitized-ref> tag
|
||||
# - sha-<short> immutable tag
|
||||
tags: |
|
||||
type=raw,value=preview-${{ steps.sanitize.outputs.suffix }}
|
||||
type=raw,value=sha-${{ steps.metadata.outputs.sha }}
|
||||
# Labels are automatically generated from git context by metadata-action
|
||||
# No need to specify them - metadata-action will create standard OCI labels
|
||||
|
||||
- name: Build and push Docker image
|
||||
id: build
|
||||
uses: ./.github/actions/docker-build
|
||||
with:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
annotations: ${{ steps.meta.outputs.annotations }}
|
||||
timestamp: ${{ steps.metadata.outputs.timestamp }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
image-name: ${{ env.IMAGE_NAME }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Print final tags
|
||||
run: |
|
||||
echo "Successfully published preview Docker image"
|
||||
echo "Tags: ${{ steps.meta.outputs.tags }}"
|
||||
echo "Image digest: ${{ steps.build.outputs.digest }}"
|
||||
@@ -0,0 +1,69 @@
|
||||
name: Validate Branch Naming
|
||||
|
||||
# Validates branch naming conventions for feature/fix/chore/deps/release branches
|
||||
# Runs only on pull requests
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
# Cancel in-progress runs for the same PR
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validate-branch-name:
|
||||
name: Validate Branch Naming Convention
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Validate branch name
|
||||
run: |
|
||||
# Extract branch name from pull request head ref
|
||||
BRANCH_NAME="${{ github.head_ref }}"
|
||||
|
||||
echo "Validating branch: $BRANCH_NAME"
|
||||
|
||||
# Check each allowed pattern
|
||||
VALID=false
|
||||
|
||||
# feature/<slug>
|
||||
if [[ "$BRANCH_NAME" =~ ^feature/[a-z0-9-]+$ ]]; then
|
||||
VALID=true
|
||||
echo "✓ Branch name matches pattern: feature/<slug>"
|
||||
# fix/<slug>
|
||||
elif [[ "$BRANCH_NAME" =~ ^fix/[a-z0-9-]+$ ]]; then
|
||||
VALID=true
|
||||
echo "✓ Branch name matches pattern: fix/<slug>"
|
||||
# chore/<slug>
|
||||
elif [[ "$BRANCH_NAME" =~ ^chore/[a-z0-9-]+$ ]]; then
|
||||
VALID=true
|
||||
echo "✓ Branch name matches pattern: chore/<slug>"
|
||||
# deps/<slug>
|
||||
elif [[ "$BRANCH_NAME" =~ ^deps/[a-z0-9-]+$ ]]; then
|
||||
VALID=true
|
||||
echo "✓ Branch name matches pattern: deps/<slug>"
|
||||
# release/<version> (e.g., release/0.6.3 or release/0.6.3-rc1)
|
||||
elif [[ "$BRANCH_NAME" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9-]+)?$ ]]; then
|
||||
VALID=true
|
||||
echo "✓ Branch name matches pattern: release/<version>"
|
||||
fi
|
||||
|
||||
if [[ "$VALID" == "false" ]]; then
|
||||
echo "❌ Branch name '$BRANCH_NAME' does not match allowed patterns:"
|
||||
echo ""
|
||||
echo "Allowed branch patterns:"
|
||||
echo " - feature/<slug> (e.g., feature/new-player-ui)"
|
||||
echo " - fix/<slug> (e.g., fix/youtube-oauth)"
|
||||
echo " - chore/<slug> (e.g., chore/update-dependencies)"
|
||||
echo " - deps/<slug> (e.g., deps/youtube-source-pr195)"
|
||||
echo " - release/<version> (e.g., release/0.6.3 or release/0.6.3-rc1)"
|
||||
echo ""
|
||||
echo "Branch names should:"
|
||||
echo " - Use lowercase letters, numbers, and hyphens only"
|
||||
echo " - Follow the pattern: <type>/<descriptive-slug>"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Branch name is valid!"
|
||||
Reference in new issue
Block a user