وضع علامة على الإصدارات باستخدام علامات Git

مكتمل

توفر علامات Git طريقة لتمييز نقاط معينة في سجل المستودع الخاص بك ، عادة للإصدارات. يعد فهم كيفية استخدام العلامات بشكل فعال أمرا ضروريا لإدارة إصدارات البرامج وإنشاء إصدارات يمكن للفرق الاعتماد عليها.

فهم علامات Git وإصداراتها

علامات Git هي مراجع تشير إلى التزامات محددة في محفوظات المستودع الخاص بك. إنهم يخلقون علامات دائمة لا تتحرك ، على عكس الفروع. تعد العلامات مثالية لتمييز نقاط الإصدار ومعالم الإصدار والالتزامات المهمة الأخرى التي تريد الرجوع إليها لاحقا.

نوعان من علامات Git:

  • علامات خفيفة الوزن: مؤشرات بسيطة لالتزامات محددة
  • العلامات المشروحة: الكائنات الكاملة مع البيانات الوصفية (موصى بها للإصدارات)

إنشاء علامات Git وإدارتها

# Create an annotated tag with a message
git tag -a v1.0.0 -m "Release version 1.0.0: Initial stable release"

# Create a tag for a specific commit
git tag -a v1.0.1 -m "Hotfix: Security vulnerability patch" abc1234

# View tag information
git show v1.0.0

إنشاء علامات خفيفة الوزن

# Create a lightweight tag (just a pointer)
git tag v1.0.0-beta

# List all tags
git tag

# List tags matching a pattern
git tag -l "v1.0.*"

دفع العلامات إلى المستودع البعيد

# Push a specific tag
git push origin v1.0.0

# Push all tags
git push origin --tags

# Push all tags (including lightweight tags)
git push origin --follow-tags

الإصدار الدلالي باستخدام علامات Git

اتبع مبادئ تعيين الإصدار الدلالي (SemVer) لإدارة الإصدار المتسقة:

# Format: MAJOR.MINOR.PATCH
git tag -a v1.0.0 -m "Major: Initial stable API"
git tag -a v1.1.0 -m "Minor: New feature additions"
git tag -a v1.1.1 -m "Patch: Bug fixes and improvements"

# Pre-release versions
git tag -a v2.0.0-alpha -m "Alpha: Pre-release for testing"
git tag -a v2.0.0-beta.1 -m "Beta: Feature-complete pre-release"
git tag -a v2.0.0-rc.1 -m "Release candidate: Final testing"

قواعد زيادة الإصدار:

  • MAJOR: كسر التغييرات التي تتطلب إجراء المستخدم
  • MINOR: ميزات جديدة تحافظ على التوافق مع الإصدارات السابقة
  • التصحيح: إصلاحات الأخطاء والتحسينات الصغيرة

أتمتة إنشاء الإصدار باستخدام GitHub Actions

سير عمل إنشاء العلامات تلقائيا

name: Create Release Tag

on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      version:
        description: "Version number (e.g., v1.2.3)"
        required: true
        type: string

jobs:
  create-tag:
    if: contains(github.event.head_commit.message, '[release]')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Get full history for tag creation

      - name: Extract version from commit message
        id: version
        run: |
          # Extract version from commit message like "[release] v1.2.3"
          VERSION=$(echo "${{ github.event.head_commit.message }}" | grep -oP '\[release\]\s*\K\S+')

          if [[ -z "$VERSION" ]]; then
            echo "No version found in commit message"
            exit 1
          fi

          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Found version: $VERSION"

      - name: Create and push tag
        run: |
          VERSION="${{ steps.version.outputs.version }}"

          # Configure git
          git config user.name "Release Bot"
          git config user.email "release-bot@company.com"

          # Create annotated tag
          git tag -a "$VERSION" -m "Release $VERSION

          Changes in this release:
          $(git log --oneline $(git describe --tags --abbrev=0)..HEAD)"

          # Push tag to remote
          git push origin "$VERSION"

          echo "Created and pushed tag: $VERSION"

تحرير الإنشاء من العلامات

name: Create GitHub Release

on:
  push:
    tags:
      - "v*" # Trigger on version tags

jobs:
  create-release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate changelog
        id: changelog
        run: |
          # Get the previous tag for changelog generation
          PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD)
          CURRENT_TAG=${GITHUB_REF#refs/tags/}

          # Generate changelog between tags
          CHANGELOG=$(git log --pretty=format:"- %s (%an)" $PREVIOUS_TAG..$CURRENT_TAG)

          # Save multiline output
          {
            echo 'changelog<<EOF'
            echo "$CHANGELOG"
            echo EOF
          } >> $GITHUB_OUTPUT

      - name: Create GitHub Release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref_name }}
          release_name: Release ${{ github.ref_name }}
          body: |
            ## Changes in ${{ github.ref_name }}

            ${{ steps.changelog.outputs.changelog }}

            ## Installation

            ### NPM
            ```bash
            npm install my-package@${{ github.ref_name }}
            ```

            ### Docker
            ```bash
            docker pull ghcr.io/myorg/myapp:${{ github.ref_name }}
            ```
          draft: false
          prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }}

استراتيجيات وضع العلامات المتقدمة

وضع العلامات الخاصة بالفرع

# Different tagging strategies for different branches
name: Smart Tagging

on:
  push:
    branches:
      - main
      - develop
      - "release/**"

jobs:
  create-tag:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Determine tag strategy
        id: strategy
        run: |
          BRANCH=${GITHUB_REF#refs/heads/}

          case $BRANCH in
            main)
              TAG_PREFIX="v"
              TAG_TYPE="stable"
              ;;
            develop)
              TAG_PREFIX="dev-"
              TAG_TYPE="development"
              ;;
            release/*)
              TAG_PREFIX="rc-"
              TAG_TYPE="release-candidate"
              ;;
            *)
              echo "No tagging for branch: $BRANCH"
              exit 0
              ;;
          esac

          # Generate version based on date and commit
          VERSION="${TAG_PREFIX}$(date +'%Y%m%d')-$(git rev-parse --short HEAD)"

          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "tag-type=$TAG_TYPE" >> $GITHUB_OUTPUT

      - name: Create tag
        if: steps.strategy.outputs.version
        run: |
          git config user.name "Auto Tagger"
          git config user.email "auto-tagger@company.com"

          git tag -a "${{ steps.strategy.outputs.version }}" \
            -m "${{ steps.strategy.outputs.tag-type }} build from ${GITHUB_SHA}"

          git push origin "${{ steps.strategy.outputs.version }}"

إدارة العلامات وتنظيمها

عرض العلامات والبحث عنها

# List all tags
git tag

# List tags with pattern matching
git tag -l "v1.*"

# Show tag details
git show v1.0.0

# Find tags containing specific commit
git tag --contains abc1234

# Sort tags by version
git tag -l | sort -V

تنظيف العلامات القديمة

# Delete local tag
git tag -d v1.0.0-beta

# Delete remote tag
git push origin --delete v1.0.0-beta

# Delete multiple tags matching pattern
git tag -l "v1.0.*-beta" | xargs git tag -d
git tag -l "v1.0.*-beta" | xargs -I {} git push origin --delete {}

أمان العلامة والتحقق منها

# Create signed tag (requires GPG setup)
git tag -s v1.0.0 -m "Signed release v1.0.0"

# Verify signed tag
git tag -v v1.0.0

# List signed tags
git tag -l --format="%(refname:short) %(taggername) %(signature)"

أفضل الممارسات لعلامات Git وإصداراتها

اصطلاحات تسمية متسقة

# Good: Semantic versioning
v1.0.0, v1.1.0, v1.1.1

# Good: Clear pre-release indicators
v2.0.0-alpha.1, v2.0.0-beta.2, v2.0.0-rc.1

# Avoid: Inconsistent naming
release-1, ver1.0, final-version

رسائل الوسم ذات المغزى

# Good: Descriptive messages
git tag -a v1.2.0 -m "Version 1.2.0

Features:
- Add user authentication system
- Implement API rate limiting
- Add database migrations

Bug fixes:
- Fix memory leak in file processing
- Resolve race condition in user sessions

Breaking changes:
- Change API endpoint structure (see migration guide)"

# Avoid: Generic messages
git tag -a v1.2.0 -m "New version"

التحقق الآلي

# Validate tags before creation
name: Tag Validation

on:
  push:
    tags:
      - "v*"

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Validate tag format
        run: |
          TAG=${GITHUB_REF#refs/tags/}

          # Check semantic versioning format
          if [[ ! $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[0-9]+)?)?$ ]]; then
            echo "Invalid tag format: $TAG"
            echo "Expected format: v1.2.3 or v1.2.3-alpha.1"
            exit 1
          fi

          echo "Valid tag format: $TAG"

      - name: Check for changelog entry
        run: |
          TAG=${GITHUB_REF#refs/tags/}

          if ! grep -q "$TAG" CHANGELOG.md; then
            echo "No changelog entry found for $TAG"
            exit 1
          fi

          echo "Changelog entry exists for $TAG"

يؤدي استخدام علامات Git بشكل فعال إلى إنشاء سجل واضح لتطور مشروعك ويوفر نقاطا مرجعية موثوقة للإصدارات وعمليات النشر والتراجع. إلى جانب أتمتة GitHub Actions، تصبح العلامات أدوات قوية لإدارة مسار تسليم البرامج الخاصة بك.