Fix incorrect docblock type annotation in LabelReconciliationJob
#174
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CI/CD Deployment Workflow with Semantic Versioning | |
| # | |
| # WORKFLOW: | |
| # - Push to 'development' branch → Deploys to DEVELOPMENT automatically | |
| # - Push to 'main' branch → Calculates version → Deploys to PRODUCTION → Creates GitHub release (only on success) | |
| # | |
| # VERSION CONTROL: | |
| # Use commit message tags to control version bumps: | |
| # - [major] or [breaking] → Major version bump (1.0.0 → 2.0.0) | |
| # - [minor] or [feature] → Minor version bump (1.0.0 → 1.1.0) | |
| # - Default (no tag) → Patch version bump (1.0.0 → 1.0.1) | |
| # | |
| # SKIP DEPLOYMENT: | |
| # Add [skip deploy] or [no deploy] to your commit message to push without deploying | |
| # | |
| # For detailed instructions, see: COMMIT_CONVENTIONS.md | |
| # | |
| name: Build and Deploy | |
| on: | |
| push: | |
| branches: | |
| - main # Calculates version, deploys to production, then creates release | |
| - development # Development environment | |
| permissions: | |
| id-token: write | |
| contents: read | |
| jobs: | |
| # Calculate the next version number — deployment and release creation happen in subsequent jobs | |
| calculate-version: | |
| runs-on: ubuntu-latest | |
| if: "github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip deploy]') && !contains(github.event.head_commit.message, '[no deploy]')" | |
| outputs: | |
| new_version: ${{ steps.new_version.outputs.new_version }} | |
| current_version: ${{ steps.version_bump.outputs.current_version }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 # Fetch all history for proper versioning | |
| - name: Determine version bump | |
| id: version_bump | |
| run: | | |
| # Get the latest tag, default to 0.0.0 if no tags exist | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0") | |
| echo "Latest tag: $LATEST_TAG" | |
| # Check commit messages in the current push for version bump indicators | |
| COMMITS=$(git log ${LATEST_TAG}..HEAD --oneline) | |
| echo "Commits since last tag:" | |
| echo "$COMMITS" | |
| # Get the specific commit message for this push (literal; do NOT let bash interpret `...`) | |
| CURRENT_COMMIT_MSG="$(cat <<'EOF' | |
| ${{ github.event.head_commit.message }} | |
| EOF | |
| )" | |
| echo "Current commit message:" | |
| printf '%s\n' "$CURRENT_COMMIT_MSG" | |
| # Determine version bump based on the current commit message only | |
| if printf '%s' "$CURRENT_COMMIT_MSG" | grep -Eqi '\[(major|breaking)\]'; then | |
| BUMP_TYPE="major" | |
| elif printf '%s' "$CURRENT_COMMIT_MSG" | grep -Eqi '\[(minor|feature)\]'; then | |
| BUMP_TYPE="minor" | |
| else | |
| BUMP_TYPE="patch" | |
| fi | |
| echo "Bump type: $BUMP_TYPE" | |
| echo "bump_type=$BUMP_TYPE" >> "$GITHUB_OUTPUT" | |
| echo "current_version=$LATEST_TAG" >> "$GITHUB_OUTPUT" | |
| - name: Calculate new version | |
| id: new_version | |
| run: | | |
| CURRENT="${{ steps.version_bump.outputs.current_version }}" | |
| BUMP_TYPE="${{ steps.version_bump.outputs.bump_type }}" | |
| # Parse current version | |
| if [[ $CURRENT =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then | |
| MAJOR=${BASH_REMATCH[1]} | |
| MINOR=${BASH_REMATCH[2]} | |
| PATCH=${BASH_REMATCH[3]} | |
| else | |
| MAJOR=0 | |
| MINOR=0 | |
| PATCH=0 | |
| fi | |
| # Increment based on bump type | |
| case $BUMP_TYPE in | |
| "major") | |
| MAJOR=$((MAJOR + 1)) | |
| MINOR=0 | |
| PATCH=0 | |
| ;; | |
| "minor") | |
| MINOR=$((MINOR + 1)) | |
| PATCH=0 | |
| ;; | |
| "patch") | |
| PATCH=$((PATCH + 1)) | |
| ;; | |
| esac | |
| NEW_VERSION="$MAJOR.$MINOR.$PATCH" | |
| echo "New version: $NEW_VERSION" | |
| echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| # Production deployment (runs after version is calculated) | |
| build-and-deploy-production: | |
| needs: calculate-version | |
| runs-on: ubuntu-latest | |
| environment: production | |
| if: "github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip deploy]') && !contains(github.event.head_commit.message, '[no deploy]')" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Get Runner IP | |
| id: ip | |
| uses: haythem/public-ip@v1.3 | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::147899039648:role/GitHubActionsDeployRole | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Whitelist Runner IP in AWS Security Group | |
| run: | | |
| aws ec2 authorize-security-group-ingress \ | |
| --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} \ | |
| --protocol tcp \ | |
| --port 22 \ | |
| --cidr ${{ steps.ip.outputs.ipv4 }}/32 | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mbstring, xml, bcmath, ctype, json, tokenizer, pdo, pdo_mysql | |
| - name: Cache Composer packages | |
| id: composer-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: vendor | |
| key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-php- | |
| - name: Install Composer dependencies | |
| run: composer install --prefer-dist --no-progress --no-suggest --no-dev --optimize-autoloader --no-scripts | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| cache: 'yarn' | |
| - name: Install Yarn dependencies | |
| run: yarn install --frozen-lockfile --ignore-engines | |
| - name: Build assets for Production | |
| run: npm run production | |
| env: | |
| MIX_REVERB_APP_KEY: ${{ vars.PROD_REVERB_APP_KEY }} | |
| MIX_REVERB_HOST: ${{ vars.PROD_REVERB_HOST }} | |
| MIX_REVERB_PORT: ${{ vars.PROD_REVERB_PORT }} | |
| MIX_REVERB_SCHEME: ${{ vars.PROD_REVERB_SCHEME }} | |
| - name: Create deployment package | |
| run: | | |
| # Clean any prior | |
| rm -rf deployment-package || true | |
| # Create isolated temp dir | |
| TEMP_DIR=$(mktemp -d) | |
| # Sync repo files to temp (exclusions prevent bloat/self-ref) | |
| rsync -av \ | |
| --exclude=node_modules \ | |
| --exclude=.git \ | |
| --exclude=.github \ | |
| --exclude=tests \ | |
| --exclude=storage/logs \ | |
| --exclude=vendor \ | |
| . "$TEMP_DIR/" | |
| # Copy assets into temp/public/ (these are already built via npm run production) | |
| cp -r public/css public/js public/fonts public/images public/svg public/mix-manifest.json "$TEMP_DIR/public/" || true | |
| # Rename to package name | |
| mv "$TEMP_DIR" deployment-package | |
| - name: Upload deployment artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: biospex-${{ github.sha }} | |
| path: deployment-package/ | |
| retention-days: 30 | |
| - name: Deploy with Deployer | |
| uses: deployphp/action@v1 | |
| with: | |
| private-key: ${{ secrets.DEPLOY_PRIVATE_KEY }} | |
| dep: deploy production | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| GITHUB_REPO: ${{ github.repository }} | |
| OPCACHE_WEBHOOK_TOKEN: ${{ secrets.OPCACHE_WEBHOOK_TOKEN }} | |
| - name: Revoke Runner IP from AWS Security Group | |
| if: always() | |
| run: | | |
| aws ec2 revoke-security-group-ingress \ | |
| --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} \ | |
| --protocol tcp \ | |
| --port 22 \ | |
| --cidr ${{ steps.ip.outputs.ipv4 }}/32 | |
| # Create release only after a successful production deployment | |
| create-release: | |
| needs: [calculate-version, build-and-deploy-production] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| if: "github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip deploy]') && !contains(github.event.head_commit.message, '[no deploy]')" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create Release | |
| run: | | |
| NOTES_FILE="$(mktemp)" | |
| cat > "$NOTES_FILE" <<'EOF' | |
| ## What's Changed | |
| Auto-generated release from main branch. | |
| **Commits included:** | |
| ``` | |
| __COMMITS_HERE__ | |
| ``` | |
| **Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ needs.calculate-version.outputs.current_version }}...${{ needs.calculate-version.outputs.new_version }} | |
| EOF | |
| # Replace placeholder with the commit message safely (no shell expansion) | |
| perl -0777 -pe 's/__COMMITS_HERE__/\Q$ENV{COMMIT_MESSAGE}\E/g' -i "$NOTES_FILE" | |
| gh release create "${{ needs.calculate-version.outputs.new_version }}" \ | |
| --title "Release ${{ needs.calculate-version.outputs.new_version }}" \ | |
| --notes-file "$NOTES_FILE" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message }} | |
| build-and-deploy-development: | |
| runs-on: ubuntu-latest | |
| environment: development | |
| # Skip deployment if commit message contains [skip deploy] or [no deploy] | |
| if: "github.ref == 'refs/heads/development' && !contains(github.event.head_commit.message, '[skip deploy]') && !contains(github.event.head_commit.message, '[no deploy]')" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Get Runner IP | |
| id: ip | |
| uses: haythem/public-ip@v1.3 | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::147899039648:role/GitHubActionsDeployRole | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Whitelist Runner IP in AWS Security Group | |
| run: | | |
| aws ec2 authorize-security-group-ingress \ | |
| --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} \ | |
| --protocol tcp \ | |
| --port 22 \ | |
| --cidr ${{ steps.ip.outputs.ipv4 }}/32 | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mbstring, xml, bcmath, ctype, json, tokenizer, pdo, pdo_mysql | |
| - name: Cache Composer packages | |
| id: composer-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: vendor | |
| key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-php- | |
| - name: Install Composer dependencies | |
| run: composer install --prefer-dist --no-progress --no-suggest --no-dev --optimize-autoloader --no-scripts | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| cache: 'yarn' | |
| - name: Install Yarn dependencies | |
| run: yarn install --frozen-lockfile --ignore-engines | |
| - name: Build assets for Development | |
| run: npm run production | |
| env: | |
| MIX_REVERB_APP_KEY: ${{ vars.DEV_REVERB_APP_KEY }} | |
| MIX_REVERB_HOST: ${{ vars.DEV_REVERB_HOST }} | |
| MIX_REVERB_PORT: ${{ vars.DEV_REVERB_PORT }} | |
| MIX_REVERB_SCHEME: ${{ vars.DEV_REVERB_SCHEME }} | |
| - name: Create deployment package | |
| run: | | |
| # Clean any prior | |
| rm -rf deployment-package || true | |
| # Create isolated temp dir | |
| TEMP_DIR=$(mktemp -d) | |
| # Sync repo files to temp (exclusions prevent bloat/self-ref) | |
| rsync -av \ | |
| --exclude=node_modules \ | |
| --exclude=.git \ | |
| --exclude=.github \ | |
| --exclude=tests \ | |
| --exclude=storage/logs \ | |
| --exclude=vendor \ | |
| . "$TEMP_DIR/" | |
| # Copy assets into temp/public/ (these are already built via npm run production) | |
| cp -r public/css public/js public/fonts public/images public/svg public/mix-manifest.json "$TEMP_DIR/public/" || true | |
| # Rename to package name | |
| mv "$TEMP_DIR" deployment-package | |
| - name: Upload deployment artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: biospex-${{ github.sha }} | |
| path: deployment-package/ | |
| retention-days: 30 | |
| - name: Deploy with Deployer | |
| uses: deployphp/action@v1 | |
| with: | |
| private-key: ${{ secrets.DEPLOY_PRIVATE_KEY }} | |
| dep: deploy development | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| GITHUB_REPO: ${{ github.repository }} | |
| OPCACHE_WEBHOOK_TOKEN: ${{ secrets.OPCACHE_WEBHOOK_TOKEN }} | |
| - name: Revoke Runner IP from AWS Security Group | |
| if: always() | |
| run: | | |
| aws ec2 revoke-security-group-ingress \ | |
| --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} \ | |
| --protocol tcp \ | |
| --port 22 \ | |
| --cidr ${{ steps.ip.outputs.ipv4 }}/32 |