AlgoDaily

Continuous Integration and Deployment

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

Why CI/CD Now

From working code to shippable code

In Project Setup and Version Control, you created a clean repo baseline. In Building a RESTful Web Service, Database Integration with Hibernate, and the Real-time Chat Application, you shaped an actual Java project. In Testing and Debugging Java Projects, you made correctness executable.

Now we connect those pieces into a repeatable delivery loop:

  • every commit is checked automatically
  • tests run without depending on your laptop
  • build artifacts are produced consistently
  • deployment becomes a controlled process, not a risky manual ritual

CI/CD is where project discipline becomes team reliability. It is also the last infrastructure lesson before applying the full workflow to the upcoming e-commerce project.

Why CI/CD Now

Pipeline Mental Model

A pipeline is a trusted conveyor belt

A CI/CD pipeline answers one question repeatedly:

Can this exact version of the project be safely promoted?

A practical Java pipeline usually has these stages:

commit
  ↓
checkout source
  ↓
compile
  ↓
run tests
  ↓
package artifact
  ↓
publish artifact
  ↓
deploy to environment

The key idea is promotion. You do not rebuild a different application for production. You build once, then promote the same artifact through environments with different configuration.

That keeps debugging honest: when staging passes and production fails, you investigate environment, configuration, data, or infrastructure—not whether a different binary was built.

Pipeline Mental Model

Trigger Choice

A Java team wants to protect the main branch from broken changes. Which CI trigger is the best default?

Build Fingerprints

Reproducibility needs evidence

A CI server is valuable because it creates a neutral build record. At minimum, every build should make it easy to answer:

  • Which Java version built this?
  • Which source revision built this?
  • What artifact was produced?
  • How can we verify it did not change?

The small Java program below simulates a build fingerprint. In a real pipeline, the commit SHA comes from Git and the artifact hash comes from the packaged JAR or Docker image.

```java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.time.Instant;

public class BuildFingerprintDemo {
    public static void main(String[] args) throws Exception {
        String commitSha = args.length > 0 ? args[0] : "local-dev-commit";
        String artifactName = "chat-service-1.0.0.jar";
        String simulatedArtifactContent = artifactName + ":" + commitSha + ":compiled-bytecode";

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(simulatedArtifactContent.getBytes(StandardCharsets.UTF_8));

        System.out.println("Build time: " + Instant.now());
        System.out.println("Java version: " + System.getProperty("java.version"));
        System.out.println("Commit: " + commitSha);
        System.out.println("Artifact: " + artifactName);
        System.out.println("SHA-256: " + toHex(hash));
    }

    private static String toHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}
```

Quality Gates

CI turns tests into gates

In Testing and Debugging Java Projects, tests helped you reason locally. In CI, those same checks become a gate that protects the shared codebase.

A quality gate should be:

  • automatic: no one manually decides whether to run it
  • fast enough: developers get feedback while the context is fresh
  • clear: failure output points toward the broken behavior
  • blocking: broken builds should not be promoted

This standalone example models a tiny gate around message validation, similar to the chat project boundary.

```java
import java.util.ArrayList;
import java.util.List;

public class QualityGateDemo {
    public static void main(String[] args) {
        List<String> failures = new ArrayList<>();

        check("normal message is valid", ChatMessageValidator.isValid("hello team"), failures);
        check("blank message is invalid", !ChatMessageValidator.isValid("   "), failures);
        check("very long message is invalid", !ChatMessageValidator.isValid("x".repeat(281)), failures);

        if (failures.isEmpty()) {
            System.out.println("QUALITY GATE PASSED: all checks green");
        } else {
            System.out.println("QUALITY GATE FAILED");
            failures.forEach(failure -> System.out.println(" - " + failure));
            System.exit(1);
        }
    }

    private static void check(String name, boolean condition, List<String> failures) {
        System.out.println("Running check: " + name);
        if (!condition) {
            failures.add(name);
        }
    }

    static class ChatMessageValidator {
        static boolean isValid(String message) {
            return message != null && !message.trim().isEmpty() && message.length() <= 280;
        }
    }
}
```

Broken Deployments

True or false: A CI/CD pipeline should deploy the application even if the test stage fails, as long as a developer promises to fix the issue later.

Deployment Boundaries

Build once, configure per environment

Deployment is not just copying files. It is moving a verified artifact into an environment with the correct runtime configuration.

Common environment-specific values include:

  • database URL
  • credentials or secret references
  • feature flags
  • logging level
  • external service endpoints

The artifact should stay the same. Configuration changes around it.

same JAR + dev config      → development
same JAR + staging config  → staging
same JAR + prod config     → production

This separation reduces the classic production mystery: "It worked on my machine."

Deployment Boundaries

Artifact Term

In CI/CD, the packaged output that is built once and promoted through environments is called an ______.

Workflow Shape

What a real workflow contains

Whether you use GitHub Actions, GitLab CI, Jenkins, or another tool, the shape is similar.

A minimal Java workflow needs:

  1. Trigger: pull request, push to main, or release tag
  2. Checkout: fetch the repository source
  3. JDK setup: install the expected Java version
  4. Dependency cache: speed up Maven or Gradle downloads
  5. Build command: usually mvn test package or gradle build
  6. Artifact upload: store the generated JAR or report
  7. Deployment step: only for approved branches or tags

The important design choice: do not hide project knowledge inside a developer laptop. Encode it in the pipeline so the team can inspect, repeat, and improve it.

Workflow Shape

Release Checklist

Before calling it deployable

For the projects in this course, use this compact release checklist:

  • Repo has a clean default branch
  • Build runs from a fresh checkout
  • Tests run automatically
  • Failures block promotion
  • Artifact is versioned or fingerprinted
  • Secrets are not committed to Git
  • Environment configuration is externalized
  • Deployment target is explicit
  • Logs can identify version and environment

CI/CD is not only tooling. It is the project’s operating system for change.

Next, you will apply the project structure, patterns, persistence, testing, and delivery mindset to a larger real-time build: an e-commerce platform.

Release Checklist

Open interactive view →