Skip to content

NM-168: Create GitHub Actions CI/CD workflow for Azure VM deployment#90

Merged
devin-ai-integration[bot] merged 1 commit into
epic-8/deploymentfrom
devin/1779774546-nm168-cicd
May 26, 2026
Merged

NM-168: Create GitHub Actions CI/CD workflow for Azure VM deployment#90
devin-ai-integration[bot] merged 1 commit into
epic-8/deploymentfrom
devin/1779774546-nm168-cicd

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented May 26, 2026

Copy link
Copy Markdown

Summary

Creates .github/workflows/deploy.yml — a GitHub Actions CI/CD pipeline for building, testing, and deploying the Spring Boot application to Azure VMs via SSH.

Pipeline stages:

Job Description
build-and-test JDK 21 setup, Maven cache, ./mvnw clean verify, Spotless check, test results via dorny/test-reporter, JaCoCo coverage upload
docker-build-push Builds Docker image, pushes to GHCR with SHA and branch tags
deploy-staging SSHs into staging VM via appleboy/ssh-action, pulls image, runs container with /opt/app/staging.env
health-check-staging Polls /actuator/health for {"status":"UP"} with retry logic
deploy-production Same SSH deployment to production VM; uses GitHub Environment protection rules (manual approval gate)

GitHub Environments:

  • staging — auto-deploy on push
  • production — requires manual approval

Required GitHub Secrets:

  • STAGING_VM_HOST, PROD_VM_HOST — VM IP/hostname
  • VM_USERNAME — SSH username
  • VM_SSH_KEY — SSH private key
  • STAGING_URL, PROD_URL — Application base URLs for health checks

Review & Testing Checklist for Human

  • Verify the workflow YAML is valid (actionlint or similar)
  • Confirm GitHub Environments (staging, production) are created with appropriate protection rules
  • Verify all required secrets are provisioned before first deployment

Notes

This is code-only — no actual Azure resources are provisioned. Part of Epic 8: Deployment Configuration.

Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/f4ae048dadcc4460a1f9d79a49342199
Requested by: @mbatchelor81


Open in Devin Review

- Trigger on push to main and migration/complete-java-migration branches
- Build & test job: JDK 21 setup, Maven cache, ./mvnw clean verify, Spotless check
- Test results published via dorny/test-reporter
- Docker build & push job: builds image and pushes to GHCR
- Staging deploy job: SSH into staging VM via appleboy/ssh-action
- Health check job: verifies /actuator/health returns UP on staging
- Production deploy job: SSH-based deployment with GitHub Environment protection
- Required secrets documented: STAGING_VM_HOST, PROD_VM_HOST, VM_USERNAME, VM_SSH_KEY, STAGING_URL, PROD_URL
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@devin-ai-integration devin-ai-integration Bot merged commit 50ee48c into epic-8/deployment May 26, 2026
1 check was pending

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

Comment on lines +112 to +120
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
docker stop eshop-catalog || true
docker rm eshop-catalog || true
docker run -d \
--name eshop-catalog \
--restart unless-stopped \
-p 8080:8080 \
--env-file /opt/app/staging.env \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Docker image tag mismatch: pushed with short SHA but pulled with full SHA

The docker/metadata-action with type=sha,prefix= generates a tag using the short git SHA (7 characters, e.g. abc1234). However, the deploy steps at lines 112, 120, 165, and 173 reference ${{ github.sha }}, which is the full 40-character commit SHA. Since no image is ever pushed with the full SHA as a tag, docker pull will fail with "image not found" on every deployment, breaking both staging and production.

Example of the mismatch

Pushed tag (from metadata-action type=sha,prefix=): ghcr.io/.../eshop-catalog:abc1234

Pulled tag (from deploy steps): ghcr.io/.../eshop-catalog:abc1234567890abcdef1234567890abcdef12345678

These don't match, so the pull always fails.

Prompt for agents
The docker/metadata-action type=sha,prefix= generates a short SHA tag (7 chars), but the deploy jobs pull using github.sha (full 40-char SHA). These don't match so docker pull will always fail.

Two possible fixes:

1. Change the metadata-action tag to use the full SHA: replace type=sha,prefix= with type=raw,value=${{github.sha}} (in the tags block at line 84). This makes the pushed tag match the full SHA used in deploys.

2. Alternatively, pass the short SHA to the deploy steps. You could use github.sha truncated to 7 chars, or output the image tag from the docker-build-push job and reference it in downstream jobs.

Option 1 is the simplest fix. The same mismatch exists in deploy-production at lines 165 and 173.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot deleted the devin/1779774546-nm168-cicd branch May 26, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant