Skip to main content

Builds

This guide walks you through setting up CI/CD and containerization for your legacy application. Rather than repeating all the technical details, it focuses on the decisions you need to make and points you to the appropriate reference documentation.

What You'll Learn

  • How to assess your current build state and choose a path forward
  • What's required vs. optional for platform deployment
  • How to adapt existing CI/CD pipelines
  • Common migration pitfalls and how to avoid them

Requirements

Optional for Initial Deployment

CI/CD automation is not required to deploy your application. If your container images are already being built and published elsewhere, you can manually update the .platform folder and skip this section initially. However, setting up CI/CD provides automated deployments and a streamlined workflow.

By the end of this section, your repository will have:

  • A Dockerfile that builds your application
  • GitHub Actions workflows for build, tag cutting, and promotion
  • Registry credentials configured as repository secrets
  • Container images publishing to your registry (Artifactory, Azure Container Registry, etc.)

Assess Your Starting Point

Your path through this guide depends on your current state:

Current StateWhat You Need
No Dockerfile, no CICreate Dockerfile + set up workflows
Has Dockerfile, no CISet up GitHub Actions workflows
Has Dockerfile + CI (not GitHub Actions)Adapt existing CI or migrate to GitHub Actions
Has Dockerfile + GitHub ActionsAdapt workflows to use p6m-actions

Read the sections below that apply to your situation.


If You Don't Have a Dockerfile

If your application isn't containerized yet, you'll need to create a Dockerfile. The platform supports any valid Docker image, but following platform patterns ensures compatibility.

Key Requirements

Your Dockerfile must:

  1. Build a runnable image — Include all runtime dependencies
  2. Expose the correct port — Match what your application listens on
  3. Use exec form for CMD — So SIGTERM reaches your process for graceful shutdown

Recommended (but not required initially):

  • Multi-stage builds for smaller images
  • Non-root user for security
  • Pinned base image versions

Where to Start

The Containerization reference provides:

  • Multi-stage Dockerfile patterns
  • Security best practices (non-root users, minimal base images)
  • Language-specific Dockerfiles for Python, Java, .NET, Rust, JavaScript
  • Layer caching strategies
  • Registry publishing patterns

For language-specific examples, see the Language Reference.

Test Locally First

Before setting up CI/CD, verify your Dockerfile works locally:

docker build -t my-app:test .
docker run -p 8080:8080 my-app:test
curl http://localhost:8080/health

If You Don't Have CI/CD

If your repository doesn't have automated builds, you'll set up GitHub Actions workflows following the platform's three-workflow pattern.

The Three-Workflow Pattern

The platform uses three workflows that work together:

WorkflowTriggerPurpose
BuildPush/PR to mainBuild, test, publish images, deploy to dev
Cut TagManualCreate minor/major releases
PromoteManualDeploy releases to staging/production

The Builds Overview explains this pattern in detail.

Setting Up Workflows

The CI/CD Overview provides complete workflow examples you can copy and adapt. It covers:

  • Pipeline stages (setup → login → build → publish → deploy)
  • Language-specific actions for each stage
  • Complete workflow files with tabs for snippet vs. full versions

For your specific language, see:

Getting Started Quickly

Contact your platform team for base workflow templates. For new solutions, Ybor Automation typically sets up the initial CI/CD configuration for you.

Configuring Repository Secrets

Already Set Up?

For new solutions, Ybor Automation typically configures these secrets automatically. Check your repository settings before adding them manually.

If using Artifactory as your registry, configure these in your GitHub repository settings (Settings → Secrets and variables → Actions):

Secrets (for Artifactory):

  • ARTIFACTORY_USERNAME
  • ARTIFACTORY_IDENTITY_TOKEN
  • UPDATE_MANIFEST_TOKEN

Variables (for Artifactory):

  • ARTIFACTORY_HOSTNAME
  • ARTIFACTORY_PROJECT
  • PLATFORM_DISPATCH_URL

If using a different registry (Azure Container Registry, ECR, etc.), configure the appropriate credentials for that registry instead.

See CI/CD Overview — Required Secrets and Variables for descriptions of each.

Organization-Level Configuration

These may already be configured at the organization level. Check with your platform team before adding them to individual repositories.


If You Have Existing CI/CD

If you already have CI/CD (Jenkins, GitLab CI, CircleCI, Azure DevOps, or GitHub Actions with custom workflows), you have options.

Replace your existing CI/CD with platform-standard GitHub Actions. This gives you:

  • Full integration with platform tooling
  • Access to p6m-actions for language-specific tasks
  • Automatic dev deployment on merge
  • Standard promotion workflows

Migration steps:

  1. Copy workflow templates from CI/CD Overview
  2. Adapt for your language using the Language Reference
  3. Configure repository secrets (see above)
  4. Test on a feature branch before removing old CI/CD
  5. Remove or disable old CI/CD configuration

Option 2: Adapt Existing CI/CD

If full migration isn't feasible (complex custom logic, organizational constraints), your existing CI/CD can work with the platform if it:

  1. Builds and pushes Docker images to your Artifactory registry
  2. Uses semantic versioning for image tags
  3. Outputs the image digest for deployment tracking
  4. Triggers platform manifest updates for deployment

The critical integration point is step 4. You'll need to call the platform dispatch API to trigger deployments. See Platform Dispatch Action for the API details, or contact your platform team.

Option 3: Hybrid Approach

Keep your existing build/test logic but add platform workflows for deployment:

  1. Keep existing CI for build and test
  2. Have it push images to Artifactory with proper tags
  3. Add platform promote.yml workflow that references your images
  4. Use the promote workflow for staging/production deployments

This works well when:

  • Your build logic is complex and well-tested
  • You want to minimize changes to working pipelines
  • You're migrating incrementally

Testing Your Pipeline

After setting up workflows, verify everything works:

Pre-Flight Checklist

  • Secrets and variables are configured in repository settings
  • Dockerfile builds successfully locally
  • You have push access to the repository

Verification Steps

  1. Create a feature branch and push — This triggers the build workflow on PR
  2. Check the Actions tab — Verify all steps pass (setup, build, test, docker build)
  3. Review any failures — Authentication issues are most common initially
  4. Merge to main — This should:
    • Build and push the image to Artifactory
    • Auto-cut a patch version
    • Dispatch a dev deployment
  5. Verify in Artifactory — Check that your image appears in the registry
  6. Check the .platform repository — A manifest update should appear

Migration-Specific Troubleshooting

These issues are common when migrating existing applications.

Authentication Failures

Symptom: Build fails immediately with 401/403 errors.

Common causes:

  • Secrets not configured or misspelled
  • Token expired or revoked
  • Service account lacks push permissions

Resolution:

  1. Verify secret names match exactly (case-sensitive)
  2. Test credentials locally if possible
  3. Request new tokens from your platform team

Docker Build Fails in CI but Works Locally

Symptom: docker build succeeds on your machine but fails in GitHub Actions.

Common causes:

  • Files excluded by .dockerignore that are needed
  • Dependencies on local environment (env vars, mounted volumes)
  • Base image not accessible from GitHub runners
  • Architecture mismatch (building on M1 Mac, running on amd64)

Resolution:

  1. Review .dockerignore for accidentally excluded files
  2. Ensure all dependencies are explicitly declared
  3. Use multi-arch builds or specify --platform linux/amd64

Existing Tests Fail in New Environment

Symptom: Tests that pass locally or in old CI fail in GitHub Actions.

Common causes:

  • Different runtime versions
  • Missing test dependencies or fixtures
  • Environment variable differences
  • Database/service dependencies not available

Resolution:

  1. Pin runtime versions explicitly in workflow
  2. Ensure test fixtures are committed or fetched
  3. Use GitHub Actions services for databases if needed
  4. Review environment variable requirements

Manifest Dispatch Fails

Symptom: Build succeeds but deployment doesn't trigger.

Common causes:

  • UPDATE_MANIFEST_TOKEN not set or lacks permissions
  • PLATFORM_DISPATCH_URL incorrect
  • .platform repository not set up for your application

Resolution:

  1. Verify token has dispatch permissions
  2. Confirm dispatch URL with platform team
  3. Ensure your app is registered in the platform repository

Version Conflicts

Symptom: Version bumping fails or creates unexpected versions.

Common causes:

  • Version file format doesn't match expected pattern
  • Git history issues preventing tag creation
  • Existing tags conflicting with new versions

Resolution:

  1. Verify version file matches language expectations (package.json, pyproject.toml, etc.)
  2. Ensure workflow has fetch-depth: 0 for full git history
  3. Check for and resolve any existing conflicting tags

Next Steps

Once your build pipeline is working:

  1. Proceed to Deployments to create PlatformApplication manifests
  2. After deployment is verified, add Observability incrementally