How to Push to a GitHub Repository in IntelliJ
In a microservice architecture, it's common for multiple services to share common functionality or utility classes. To handle this effectively, I manage these shared components as a reusable library (like libs.jar) that each service can depend on. In this post, I’ll show you how I use GCP Artifact Registry to efficiently manage and distribute a shared library across microservices.
$ gcloud services enable artifactregistry.googleapis.com --project=[PROJECT_ID]
$ gcloud artifacts repositories create maven-repo \
--repository-format=maven \
--location=us-central1 \
--description="Shared Maven Repo for common libraries"
$ gcloud artifacts repositories list --location=us-central1
REPOSITORY FORMAT LOCATION DESCRIPTION
maven-repo MAVEN us-central1 Shared Maven repo
pom.xml for the Shared Library ProjectIn the shared library (libs) project's pom.xml, I define the following:
com.example.libs)libs)1.0.1)jar is recommended for reusable libraries)If the packaging tag is missing or incorrect, Maven may mistakenly treat the library as pom, war, or another type — leading to problems when uploading to Artifact Registry or importing it into other projects.
<groupId>com.example.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
GCP Artifact Registry for Maven requires using the artifactregistry:// protocol instead of https://. Otherwise, authentication and upload may not work properly.
For snapshot versions (e.g., 0.0.1-SNAPSHOT), Maven appends a timestamp to ensure uniqueness. Release versions remain fixed.
<distributionManagement>
<snapshotRepository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
</snapshotRepository>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
</repository>
</distributionManagement>
| Version Type | Example | Description |
|---|---|---|
<releases> |
1.0.0 |
Stable release; cannot be overwritten once uploaded |
<snapshots> |
0.0.1-SNAPSHOT |
Development version; overwritten with timestamped versions |
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Add Artifact Registry Maven Wagon Extension
To allow Maven to understand the artifactregistry://... protocol, I include the official Google Artifact Registry Maven Wagon extension.
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.2.5</version>
</extension>
</extensions>
</build>
application.yaml for the Shared LibraryI disable unnecessary auto-configuration to avoid errors — especially since the shared library doesn't require a database.
spring:
application:
name: libs
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Artifact Registry requires authentication. Since the access token from gcloud auth print-access-token only lasts 1 hour, I use the credential helper provided by gcloud to handle automatic token renewal for Maven.
On Windows, the credentials are stored in:
C:\Users\[USER]\AppData\Roaming\gcloud\application_default_credentials.json
I run the following command to enable this:
$ gcloud auth application-default login
In CI/CD environments like Cloud Build, I make sure the service account has the necessary roles to access Artifact Registry.
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.reader"
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.writer"
settings.xml for MavenSince Cloud Build runs on a remote server and doesn't have access to my local ~/.m2/settings.xml, I include a settings.xml file in the build context (the project's root directory) and explicitly specify it using the -s option.
<settings>
<servers>
<server>
<id>artifact-registry</id>
<username>oauth2accesstoken</username>
<password>
<!-- empty is fine; gcloud helper will inject the token -->
</password>
</server>
</servers>
</settings>
On my local machine, Maven uses:
C:\Users\[USER]\.m2\settings.xml
cloudbuild.yaml-DskipTests to skip running tests, which speeds up the build process. This is especially useful for shared libraries that are frequently updated and published..) to /workspace inside the build container.-B to enable batch mode, which makes the Maven output cleaner.steps:
# 1. Build the JAR without running tests
- name: 'gcr.io/cloud-builders/mvn'
entrypoint: 'mvn'
args: ['clean', 'package', '-DskipTests']
# 2. Deploy the JAR to Artifact Registry
- name: 'gcr.io/cloud-builders/mvn'
args: ['deploy',
'-B',
'-s', '/workspace/settings.xml']
pom.xml of Each ServicesIn this step, I configure each microservice (a-service, b-service, etc.) to use the shared library.
<dependency>
<groupId>com.example.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.1</version>
</dependency>
libs project.<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.2.5</version>
</extension>
artifactregistry:// URLs.<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
[PROJECT_ID] with your actual GCP project ID.us-central1) matches where your Artifact Registry is located.To enable Maven to authenticate with GCP Artifact Registry during the build the services, the following command to configure authentication for gcloud:
$ gcloud auth application-default login
Next, I place a settings.xml file in the root directory of the service. This file provides the necessary credentials using oauth2accesstoken, allowing Maven to access the GCP Artifact Registry and retrieve the shared library during the build.
<settings>
<servers>
<server>
<id>artifact-registry</id>
<username>oauth2accesstoken</username>
<password>
<!-- empty is fine; gcloud helper will inject the token -->
</password>
</server>
</servers>
</settings>
Then, I reference this file explicitly in the cloudbuild.yaml using the -s flag:
steps:
# 1. Java Build
- name: 'gcr.io/cloud-builders/mvn'
args: ['clean', 'package',
'-DskipTests',
'-B',
'-s', '/workspace/settings.xml']
Comments
Post a Comment