feat: enhance PACS008 agent fields with full CBPR+ compliance and fix… #64
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
| name: Automated Azure Deployment | |
| permissions: | |
| contents: write | |
| issues: write | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: 'Environment to deploy to' | |
| required: true | |
| default: 'production' | |
| type: choice | |
| options: | |
| - production | |
| - staging | |
| force_setup: | |
| description: 'Force Azure infrastructure setup' | |
| required: false | |
| default: false | |
| type: boolean | |
| version_bump: | |
| description: 'Version bump type' | |
| required: false | |
| default: 'patch' | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| skip_release: | |
| description: 'Skip creating GitHub release' | |
| required: false | |
| default: false | |
| type: boolean | |
| env: | |
| RESOURCE_GROUP: rg-reframe-prod | |
| LOCATION: eastus | |
| IMAGE_NAME: reframe | |
| CONTAINER_NAME: reframe-api | |
| SERVICE_PRINCIPAL_NAME: sp-reframe-cicd | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Rust | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: stable | |
| override: true | |
| components: rustfmt, clippy | |
| - name: Cache cargo dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| - name: Format check | |
| run: cargo fmt -- --check | |
| - name: Clippy check | |
| run: cargo clippy -- -D warnings | |
| - name: Run tests | |
| run: cargo test | |
| version-and-release: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| tag: ${{ steps.version.outputs.tag }} | |
| changelog: ${{ steps.version.outputs.changelog }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure Git | |
| run: | | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| - name: Install cargo-edit for version bumping | |
| run: cargo install cargo-edit | |
| - name: Get current version | |
| id: current-version | |
| run: | | |
| CURRENT_VERSION=$(grep '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| echo "Current version: $CURRENT_VERSION" | |
| - name: Determine version bump type | |
| id: bump-type | |
| run: | | |
| if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
| BUMP_TYPE="${{ github.event.inputs.version_bump }}" | |
| else | |
| # Auto-determine based on commit messages | |
| if git log --format=%B -n 20 | grep -qE '\[major\]|\bbreaking\b|\bBREAKING\b'; then | |
| BUMP_TYPE="major" | |
| elif git log --format=%B -n 20 | grep -qE '\[minor\]|\bfeat\b|\bfeature\b'; then | |
| BUMP_TYPE="minor" | |
| else | |
| BUMP_TYPE="patch" | |
| fi | |
| fi | |
| echo "type=$BUMP_TYPE" >> $GITHUB_OUTPUT | |
| echo "Version bump type: $BUMP_TYPE" | |
| - name: Bump version | |
| id: version | |
| run: | | |
| BUMP_TYPE="${{ steps.bump-type.outputs.type }}" | |
| # Bump version in Cargo.toml | |
| cargo set-version --bump $BUMP_TYPE | |
| # Get new version | |
| NEW_VERSION=$(grep '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/') | |
| TAG="v$NEW_VERSION" | |
| echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "Bumped version to: $NEW_VERSION" | |
| echo "Git tag will be: $TAG" | |
| # Generate changelog | |
| PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -n "$PREVIOUS_TAG" ]; then | |
| echo "Generating changelog from $PREVIOUS_TAG to HEAD" | |
| CHANGELOG=$(git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..HEAD --no-merges | head -20) | |
| else | |
| echo "No previous tag found, generating changelog from recent commits" | |
| CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges -10) | |
| fi | |
| # Save changelog to output (escape for GitHub Actions) | |
| { | |
| echo "changelog<<EOF" | |
| echo "$CHANGELOG" | |
| echo "EOF" | |
| } >> $GITHUB_OUTPUT | |
| - name: Update Cargo.lock | |
| run: | | |
| cargo check --quiet | |
| echo "Cargo.lock updated" | |
| - name: Commit version bump | |
| run: | | |
| git add Cargo.toml Cargo.lock | |
| git commit -m "chore: bump version to ${{ steps.version.outputs.version }}" | |
| git push origin main | |
| - name: Create and push tag | |
| run: | | |
| git tag ${{ steps.version.outputs.tag }} | |
| git push origin ${{ steps.version.outputs.tag }} | |
| echo "Created and pushed tag: ${{ steps.version.outputs.tag }}" | |
| - name: Create GitHub Release | |
| if: github.event.inputs.skip_release != 'true' | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ steps.version.outputs.tag }} | |
| release_name: Release ${{ steps.version.outputs.tag }} | |
| body: | | |
| ## Changes in ${{ steps.version.outputs.tag }} | |
| ${{ steps.version.outputs.changelog }} | |
| ## Deployment Information | |
| - **Environment**: Production | |
| - **Build**: ${{ github.sha }} | |
| - **Workflow**: [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) | |
| draft: false | |
| prerelease: ${{ contains(steps.version.outputs.version, 'alpha') || contains(steps.version.outputs.version, 'beta') || contains(steps.version.outputs.version, 'rc') }} | |
| build-web-ui: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: 'web-ui/package-lock.json' | |
| - name: Install dependencies | |
| run: | | |
| cd web-ui | |
| npm ci | |
| - name: Build web UI | |
| run: | | |
| cd web-ui | |
| npm run build | |
| - name: Prepare static files | |
| run: | | |
| mkdir -p static | |
| cp -r web-ui/build/* static/ | |
| - name: Upload static files artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: static-files | |
| path: static/ | |
| retention-days: 1 | |
| setup-azure-infrastructure: | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' | |
| outputs: | |
| registry-name: ${{ steps.setup.outputs.registry-name || steps.existing-setup.outputs.registry-name }} | |
| setup-required: ${{ steps.check.outputs.setup-required }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Login to Azure | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Check if infrastructure setup is required | |
| id: check | |
| run: | | |
| # Check if resource group exists | |
| if az group show --name ${{ env.RESOURCE_GROUP }} &> /dev/null; then | |
| echo "Resource group exists" | |
| # Check if ACR exists | |
| REGISTRY_COUNT=$(az acr list --resource-group ${{ env.RESOURCE_GROUP }} --query "length(@)" --output tsv) | |
| if [ "$REGISTRY_COUNT" -gt 0 ]; then | |
| echo "setup-required=false" >> $GITHUB_OUTPUT | |
| echo "Infrastructure already exists" | |
| else | |
| echo "setup-required=true" >> $GITHUB_OUTPUT | |
| echo "ACR not found, setup required" | |
| fi | |
| else | |
| echo "setup-required=true" >> $GITHUB_OUTPUT | |
| echo "Resource group not found, setup required" | |
| fi | |
| # Force setup if requested | |
| if [ "${{ github.event.inputs.force_setup }}" == "true" ]; then | |
| echo "setup-required=true" >> $GITHUB_OUTPUT | |
| echo "Force setup requested" | |
| fi | |
| - name: Register Azure Resource Providers | |
| if: steps.check.outputs.setup-required == 'true' | |
| run: | | |
| echo "🔧 Registering Azure Resource Providers..." | |
| PROVIDERS=( | |
| "Microsoft.ContainerInstance" | |
| "Microsoft.ContainerRegistry" | |
| "Microsoft.Network" | |
| "Microsoft.Resources" | |
| ) | |
| for PROVIDER in "${PROVIDERS[@]}"; do | |
| echo "Checking: $PROVIDER" | |
| PROVIDER_STATE=$(az provider show --namespace "$PROVIDER" --query "registrationState" --output tsv 2>/dev/null || echo "NotRegistered") | |
| if [ "$PROVIDER_STATE" != "Registered" ]; then | |
| echo "🔄 Registering $PROVIDER..." | |
| az provider register --namespace "$PROVIDER" | |
| # Wait for registration with timeout | |
| TIMEOUT=300 # 5 minutes | |
| ELAPSED=0 | |
| while [ "$(az provider show --namespace "$PROVIDER" --query 'registrationState' --output tsv 2>/dev/null || echo 'NotRegistered')" != "Registered" ] && [ $ELAPSED -lt $TIMEOUT ]; do | |
| echo " Waiting for $PROVIDER registration... (${ELAPSED}s)" | |
| sleep 15 | |
| ELAPSED=$((ELAPSED + 15)) | |
| done | |
| if [ $ELAPSED -ge $TIMEOUT ]; then | |
| echo "⚠️ Warning: $PROVIDER registration timed out, but continuing..." | |
| else | |
| echo "✅ $PROVIDER registered successfully" | |
| fi | |
| else | |
| echo "✅ $PROVIDER already registered" | |
| fi | |
| done | |
| - name: Create Resource Group | |
| if: steps.check.outputs.setup-required == 'true' | |
| run: | | |
| echo "🏗️ Creating resource group: ${{ env.RESOURCE_GROUP }}" | |
| az group create --name ${{ env.RESOURCE_GROUP }} --location ${{ env.LOCATION }} | |
| - name: Deploy Azure Infrastructure | |
| id: setup | |
| if: steps.check.outputs.setup-required == 'true' | |
| run: | | |
| echo "🚀 Deploying Azure infrastructure..." | |
| az deployment group create \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --template-file infrastructure/azure-setup.bicep \ | |
| --parameters environment=prod deployContainer=false | |
| # Get registry name | |
| REGISTRY_NAME=$(az acr list --resource-group ${{ env.RESOURCE_GROUP }} --query "[0].name" --output tsv) | |
| echo "registry-name=$REGISTRY_NAME" >> $GITHUB_OUTPUT | |
| # Enable admin user | |
| az acr update --name $REGISTRY_NAME --admin-enabled true | |
| echo "✅ Infrastructure setup completed" | |
| echo "📦 Registry: $REGISTRY_NAME.azurecr.io" | |
| - name: Get existing registry name | |
| id: existing-setup | |
| if: steps.check.outputs.setup-required == 'false' | |
| run: | | |
| REGISTRY_NAME=$(az acr list --resource-group ${{ env.RESOURCE_GROUP }} --query "[0].name" --output tsv) | |
| echo "registry-name=$REGISTRY_NAME" >> $GITHUB_OUTPUT | |
| echo "📦 Using existing registry: $REGISTRY_NAME.azurecr.io" | |
| build-and-push: | |
| needs: [test, build-web-ui, setup-azure-infrastructure, version-and-release] | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' | |
| outputs: | |
| image-tag: ${{ steps.meta.outputs.tags }} | |
| image-digest: ${{ steps.build.outputs.digest }} | |
| registry-name: ${{ needs.setup-azure-infrastructure.outputs.registry-name }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: main # Ensure we get the updated version | |
| - name: Download static files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: static-files | |
| path: static/ | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Azure | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Get ACR credentials | |
| id: acr-creds | |
| run: | | |
| REGISTRY_NAME="${{ needs.setup-azure-infrastructure.outputs.registry-name }}" | |
| ACR_USERNAME=$(az acr credential show --name $REGISTRY_NAME --query username --output tsv) | |
| ACR_PASSWORD=$(az acr credential show --name $REGISTRY_NAME --query passwords[0].value --output tsv) | |
| echo "::add-mask::$ACR_PASSWORD" | |
| echo "username=$ACR_USERNAME" >> $GITHUB_OUTPUT | |
| echo "password=$ACR_PASSWORD" >> $GITHUB_OUTPUT | |
| - name: Login to Azure Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ needs.setup-azure-infrastructure.outputs.registry-name }}.azurecr.io | |
| username: ${{ steps.acr-creds.outputs.username }} | |
| password: ${{ steps.acr-creds.outputs.password }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ needs.setup-azure-infrastructure.outputs.registry-name }}.azurecr.io/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix=sha-,format=short | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| type=raw,value=${{ needs.version-and-release.outputs.version }} | |
| type=raw,value=${{ needs.version-and-release.outputs.tag }} | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: | | |
| ${{ steps.meta.outputs.labels }} | |
| org.opencontainers.image.version=${{ needs.version-and-release.outputs.version }} | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| deploy-staging: | |
| needs: [build-and-push, version-and-release] | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| environment: staging | |
| steps: | |
| - name: Login to Azure | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Extract short SHA | |
| id: sha | |
| run: echo "short=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT | |
| - name: Get ACR credentials | |
| id: acr-creds | |
| run: | | |
| REGISTRY_NAME="${{ needs.build-and-push.outputs.registry-name }}" | |
| ACR_USERNAME=$(az acr credential show --name $REGISTRY_NAME --query username --output tsv) | |
| ACR_PASSWORD=$(az acr credential show --name $REGISTRY_NAME --query passwords[0].value --output tsv) | |
| echo "::add-mask::$ACR_PASSWORD" | |
| echo "username=$ACR_USERNAME" >> $GITHUB_OUTPUT | |
| echo "password=$ACR_PASSWORD" >> $GITHUB_OUTPUT | |
| - name: Deploy to Azure Container Instances (Staging) | |
| uses: azure/aci-deploy@v1 | |
| with: | |
| resource-group: ${{ env.RESOURCE_GROUP }} | |
| dns-name-label: reframe-api-staging-${{ steps.sha.outputs.short }} | |
| image: ${{ needs.build-and-push.outputs.registry-name }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ needs.version-and-release.outputs.version }} | |
| name: ${{ env.CONTAINER_NAME }}-staging | |
| location: ${{ env.LOCATION }} | |
| cpu: 0.5 | |
| memory: 1 | |
| ports: '3000' | |
| protocol: TCP | |
| environment-variables: | | |
| RUST_LOG=info | |
| PORT=3000 | |
| APP_VERSION=${{ needs.version-and-release.outputs.version }} | |
| registry-login-server: ${{ needs.build-and-push.outputs.registry-name }}.azurecr.io | |
| registry-username: ${{ steps.acr-creds.outputs.username }} | |
| registry-password: ${{ steps.acr-creds.outputs.password }} | |
| - name: Test staging deployment | |
| run: | | |
| # Wait for container to be ready | |
| sleep 30 | |
| # Get the FQDN | |
| FQDN=$(az container show \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name ${{ env.CONTAINER_NAME }}-staging \ | |
| --query ipAddress.fqdn \ | |
| --output tsv) | |
| echo "🧪 Testing staging deployment at: http://${FQDN}:3000" | |
| echo "📦 Version: ${{ needs.version-and-release.outputs.version }}" | |
| # Test the health endpoint | |
| curl -f "http://${FQDN}:3000/health" || echo "Health check endpoint not available" | |
| # Test the main API endpoint with sample data | |
| echo "Testing main API endpoint..." | |
| curl -X POST "http://${FQDN}:3000/reframe" \ | |
| -H "Content-Type: text/plain" \ | |
| -d "{1:F01BNPAFRPPXXX0000000000}{2:O1031234240101DEUTDEFFXXXX12345678952401011234N}{3:{103:EBA}}{4: | |
| :20:FT21001234567890 | |
| :23B:CRED | |
| :32A:240101USD1000,00 | |
| :50K:/1234567890 | |
| ACME CORPORATION | |
| :52A:BNPAFRPPXXX | |
| :57A:DEUTDEFFXXX | |
| :59:/DE89370400440532013000 | |
| MUELLER GMBH | |
| :70:PAYMENT FOR INVOICE 12345 | |
| :71A:OUR | |
| -}" \ | |
| --max-time 30 \ | |
| -w "\nHTTP Status: %{http_code}\n" || echo "API test failed" | |
| deploy-production: | |
| needs: [build-and-push, deploy-staging, version-and-release] | |
| runs-on: ubuntu-latest | |
| if: (github.ref == 'refs/heads/main' && github.event_name == 'push') || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production') | |
| environment: production | |
| outputs: | |
| aci-fqdn: ${{ steps.get-fqdn.outputs.fqdn }} | |
| steps: | |
| - name: Login to Azure | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Extract short SHA | |
| id: sha | |
| run: echo "short=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT | |
| - name: Get ACR credentials | |
| id: acr-creds | |
| run: | | |
| REGISTRY_NAME="${{ needs.build-and-push.outputs.registry-name }}" | |
| ACR_USERNAME=$(az acr credential show --name $REGISTRY_NAME --query username --output tsv) | |
| ACR_PASSWORD=$(az acr credential show --name $REGISTRY_NAME --query passwords[0].value --output tsv) | |
| echo "::add-mask::$ACR_PASSWORD" | |
| echo "username=$ACR_USERNAME" >> $GITHUB_OUTPUT | |
| echo "password=$ACR_PASSWORD" >> $GITHUB_OUTPUT | |
| - name: Deploy to Azure Container Instances (Production) | |
| uses: azure/aci-deploy@v1 | |
| with: | |
| resource-group: ${{ env.RESOURCE_GROUP }} | |
| dns-name-label: reframe-api-prod | |
| image: ${{ needs.build-and-push.outputs.registry-name }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ needs.version-and-release.outputs.version }} | |
| name: ${{ env.CONTAINER_NAME }}-prod | |
| location: ${{ env.LOCATION }} | |
| cpu: 1 | |
| memory: 2 | |
| ports: '3000' | |
| protocol: TCP | |
| environment-variables: | | |
| RUST_LOG=info | |
| PORT=3000 | |
| APP_VERSION=${{ needs.version-and-release.outputs.version }} | |
| registry-login-server: ${{ needs.build-and-push.outputs.registry-name }}.azurecr.io | |
| registry-username: ${{ steps.acr-creds.outputs.username }} | |
| registry-password: ${{ steps.acr-creds.outputs.password }} | |
| - name: Get production endpoint | |
| id: get-fqdn | |
| run: | | |
| FQDN=$(az container show \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name ${{ env.CONTAINER_NAME }}-prod \ | |
| --query ipAddress.fqdn \ | |
| --output tsv) | |
| echo "fqdn=$FQDN" >> $GITHUB_OUTPUT | |
| echo "🚀 Production deployment successful!" | |
| echo "📦 Version: ${{ needs.version-and-release.outputs.version }}" | |
| echo "🏷️ Tag: ${{ needs.version-and-release.outputs.tag }}" | |
| echo "Web UI: http://${FQDN}:3000/" | |
| echo "API endpoint: http://${FQDN}:3000/reframe" | |
| echo "Health check: http://${FQDN}:3000/health" | |
| - name: Test production deployment | |
| run: | | |
| FQDN="${{ steps.get-fqdn.outputs.fqdn }}" | |
| # Wait for container to be ready | |
| sleep 30 | |
| echo "🧪 Testing production deployment..." | |
| echo "📦 Version: ${{ needs.version-and-release.outputs.version }}" | |
| # Test health endpoint | |
| echo "Testing health endpoint..." | |
| curl -f "http://${FQDN}:3000/health" || echo "Health check failed" | |
| # Test web UI (check if index.html is served) | |
| echo "Testing web UI..." | |
| curl -f "http://${FQDN}:3000/" | grep -q "Reframe" || echo "Web UI test failed" | |
| # Test API endpoint | |
| echo "Testing API endpoint..." | |
| curl -X POST "http://${FQDN}:3000/reframe" \ | |
| -H "Content-Type: text/plain" \ | |
| -d "{1:F01BNPAFRPPXXX0000000000}{2:O1031234240101DEUTDEFFXXXX12345678952401011234N}{3:{103:EBA}}{4: | |
| :20:FT21001234567890 | |
| :23B:CRED | |
| :32A:240101USD1000,00 | |
| :50K:/1234567890 | |
| ACME CORPORATION | |
| :52A:BNPAFRPPXXX | |
| :57A:DEUTDEFFXXX | |
| :59:/DE89370400440532013000 | |
| MUELLER GMBH | |
| :70:PAYMENT FOR INVOICE 12345 | |
| :71A:OUR | |
| -}" \ | |
| --max-time 30 \ | |
| -w "\nHTTP Status: %{http_code}\n" || echo "API test failed" | |
| echo "" | |
| echo "🎉 All tests completed!" | |
| echo "✅ Version: ${{ needs.version-and-release.outputs.version }}" | |
| echo "✅ Web UI: http://${FQDN}:3000/" | |
| echo "✅ API: http://${FQDN}:3000/reframe" | |
| - name: Update GitHub Release with deployment info | |
| if: needs.version-and-release.outputs.tag != '' | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fqdn = "${{ steps.get-fqdn.outputs.fqdn }}"; | |
| const version = "${{ needs.version-and-release.outputs.version }}"; | |
| const tag = "${{ needs.version-and-release.outputs.tag }}"; | |
| try { | |
| // Get the release | |
| const release = await github.rest.repos.getReleaseByTag({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag: tag | |
| }); | |
| // Update the release body with deployment information | |
| const updatedBody = release.data.body + ` | |
| ## 🚀 Deployment Completed | |
| - **Production URL**: [http://${fqdn}:3000/](http://${fqdn}:3000/) | |
| - **API Endpoint**: [http://${fqdn}:3000/reframe](http://${fqdn}:3000/reframe) | |
| - **Health Check**: [http://${fqdn}:3000/health](http://${fqdn}:3000/health) | |
| - **Deployed At**: ${new Date().toISOString()} | |
| - **Git SHA**: ${context.sha}`; | |
| await github.rest.repos.updateRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: release.data.id, | |
| body: updatedBody | |
| }); | |
| console.log(`Updated release ${tag} with deployment information`); | |
| } catch (error) { | |
| console.log(`Could not update release: ${error.message}`); | |
| } | |
| cleanup-staging: | |
| needs: [deploy-production] | |
| runs-on: ubuntu-latest | |
| if: success() | |
| steps: | |
| - name: Login to Azure | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Cleanup staging environment | |
| run: | | |
| az container delete \ | |
| --resource-group ${{ env.RESOURCE_GROUP }} \ | |
| --name ${{ env.CONTAINER_NAME }}-staging \ | |
| --yes || echo "Staging container not found or already deleted" |