Topic 5.1
Why Artifact Repositories Exist
In one line
Rebuilding an application fresh at every stage of a pipeline risks the new build being subtly different from the one that was actually tested — an artifact repository stores the exact, tested binary once, so every later stage uses that exact same thing.
Think of it like this
Testing one specific, physical prototype car thoroughly, then deciding to build a SECOND, supposedly-identical car to actually sell — even with the same blueprints, subtle differences in materials or assembly could exist. An artifact repository is the decision to ship the EXACT prototype that was actually tested, not a fresh rebuild that's merely supposed to be identical.
Key ideas
- 01
Without an artifact repository, a genuinely common (and genuinely risky) pattern is REBUILDING the application fresh at each pipeline stage — build once to run tests, then build AGAIN to actually deploy. Even with identical source code, a fresh build can differ subtly (a dependency resolved to a slightly different version if a range wasn't pinned exactly, a different build-time environment) from the one that was actually tested.
- 02
'BUILD ONCE, DEPLOY MANY TIMES' is the standard, safer principle this problem leads to: build the artifact EXACTLY ONCE, run every test against that EXACT artifact, and if it passes, that EXACT SAME artifact (never rebuilt) is what actually gets deployed — genuinely guaranteeing what's deployed is precisely what was tested, with zero possibility of drift between the two.
- 03
An ARTIFACT REPOSITORY is where that built artifact is stored after being produced, addressable by a specific, unique identifier (a version number, a build number, or a content hash) — later pipeline stages (deploying to staging, then production) retrieve that EXACT artifact from the repository by its identifier, rather than rebuilding anything at all.
- 04
This directly extends Phase 0.3's build systems — Maven's own local repository (
~/.m2) is a personal, single-machine version of this exact same idea; a real artifact repository (Nexus, JFrog Artifactory, or a container registry, all covered in this phase's remaining topics) is the shared, team-wide, genuinely durable version every pipeline stage and every team member can reliably pull from. - 05
Genuinely important corollary: an artifact, once published to a repository, should be treated as IMMUTABLE — never overwritten or silently changed after the fact. If
myapp-1.4.0.jarneeds a fix, the correct move is publishingmyapp-1.4.1.jaras a genuinely new artifact, never quietly replacing the old one's content under the same identifier, which would silently break the exact 'what's deployed matches what was tested' guarantee this whole topic is about.
Code & diagrams
One build, one artifact, tested once — then that exact same thing moves through every environment.
Build and test exactly once; deploy stages retrieve, never rebuild.
stages:
- build
- test
- deploy-staging
- deploy-production
build:
stage: build
script:
- mvn clean package
- mvn deploy:deploy-file -Dfile=target/myapp.jar -DrepositoryId=my-repo \
-Durl=https://artifacts.example.com/releases -DgroupId=com.example \
-DartifactId=myapp -Dversion=$CI_PIPELINE_ID -Dpackaging=jar
test:
stage: test
script:
- mvn test # runs against the SAME source, before the artifact above is trusted
deploy-staging:
stage: deploy-staging
script:
# RETRIEVES the exact already-built artifact — does NOT rebuild it
- curl -O https://artifacts.example.com/releases/myapp/$CI_PIPELINE_ID/myapp.jar
- ./deploy.sh staging myapp.jar
deploy-production:
stage: deploy-production
when: manual
script:
# the EXACT SAME artifact, identified the same way, deployed to production
- curl -O https://artifacts.example.com/releases/myapp/$CI_PIPELINE_ID/myapp.jar
- ./deploy.sh production myapp.jarExplain it without notes
Why is rebuilding an application separately for staging and for production a genuine risk, even when both builds use identical source code?
Why should an artifact, once published to a repository, be treated as immutable rather than updated in place?
Practice
For a hypothetical pipeline you're familiar with (or a real one), identify whether it currently rebuilds the application at each deployment stage or genuinely reuses one built artifact — if it rebuilds, describe one concrete way that could cause a real discrepancy.
Explain, in one sentence, why myapp-1.4.0.jar should never be silently replaced with different content under that exact same filename/version.
Trade-offs
- ↔
Build-once-deploy-many is close to a strict improvement in safety and traceability over rebuilding at each stage, but it does require a genuine ARTIFACT REPOSITORY to actually exist and be reliably available — for an extremely small, low-stakes project, this is real added infrastructure to set up and maintain; the safety benefit is almost always worth it the moment more than one environment or more than one person is genuinely involved in a deployment's path.
Done when you can
I can explain the real risk of rebuilding an application separately for each deployment environment.
I understand the build-once-deploy-many principle and why it's safer.
I understand why a published artifact should be treated as immutable, never silently overwritten.