Fermer

juillet 25, 2024

Comment suivre les informations de build Git dans votre projet Maven multimodule AEM / Blogs / Perficient

Comment suivre les informations de build Git dans votre projet Maven multimodule AEM / Blogs / Perficient


Lors du dépannage des problèmes dans Adobe Experience Manager (AEM), la première étape consiste souvent à identifier la version de code déployée pour les projets concernés. Cependant, les versions du bundle OSGi ne fournissent qu’une image partielle, manquant de détails cruciaux comme la branche exacte utilisée. Cela devient particulièrement problématique lors de la gestion de plusieurs locataires dans le même environnement ou lors de la comparaison de code dans différents environnements, ce qui nécessite une navigation fastidieuse dans les historiques d’outils CI/CD comme Jenkins.

La solution : débloquer la transparence de Git Build

Pour rationaliser les flux de travail de développement et la résolution des problèmes, il est essentiel de mettre en œuvre une solution qui affiche clairement les informations Git vitales, notamment les noms de branches et les identifiants de validation. En suivant et en enregistrant avec précision ces données, des équipes comme Dev/QA peuvent vérifier l’intégrité du code avant de commencer leurs tâches, garantissant ainsi une expérience plus fluide et plus efficace.

Puissance du plugin git-commit-id

Le but du plugin git-commit-id est de générer à chaque fois un fichier de propriétés contenant les informations de build Git. une version Maven est exécuté. Ce fichier peut ensuite être utilisé dans nos systèmes backend et exposé à des fins de suivi.

Examinons maintenant les étapes de mise en œuvre et d’exposition de ces informations de build.

Intégration du plugin git-commit-id dans POM.xml

Nous commençons par ajouter et configurer le plugin git-commit-id dans le fichier POM.xml de notre projet. Ce plugin sera chargé de générer le fichier de propriétés nécessaire contenant les détails de la build Git pendant le processus de build Maven.

Développement d’un service OSGi personnalisé

Ensuite, créez un service OSGi personnalisé dans notre projet Adobe Experience Manager (AEM). Ce service est conçu pour lire le fichier de propriétés généré et extraire les informations de construction pertinentes. Ce faisant, nous garantissons que ces données sont facilement disponibles dans notre environnement AEM.

Implémentation du servlet Sling

Pour exposer les informations de build récupérées par le service OSGi, nous avons développé un servlet Sling. Cette servlet exploite le service OSGi pour accéder aux détails de la build Git, puis rend ces informations accessibles via un point de terminaison désigné. Grâce à ce point de terminaison, d’autres composants de notre projet AEM ou des systèmes externes peuvent facilement accéder et utiliser les informations de build selon leurs besoins.

Commençons par ajouter les modifications POM pour le plugin.

Sous le noyau paquet POM dans la fichedans les sections de construction, ajoutez une entrée pour le plug git-commit-iddans.

<plugin> 
    <groupId>pl.project13.maven</groupId> 
    <artifactId>git-commit-id-plugin</artifactId> 
    <version>2.2.4</version> 
    <executions> 
        <execution> 
            <id>get-the-git-infos</id> 
            <goals> 
                <goal>revision</goal> 
            </goals> 
        </execution> 
 
    </executions> 
    <configuration> 
        <dotGitDirectory>${project.basedir}/.git</dotGitDirectory> 
        <prefix>git</prefix> 
        <verbose>false</verbose> 
        <generateGitPropertiesFile>true</generateGitPropertiesFile> 
        <generateGitPropertiesFilename>src/main/resources/my-project-git-response 

</generateGitPropertiesFilename> 
        <format>json</format> 
        <dateFormat>yyyy-MM-dd-HH-mm</dateFormat> 
        <gitDescribe> 
            <skip>false</skip> 
            <always>false</always> 
            <dirty>-dirty</dirty> 
        </gitDescribe> 
        <includeOnlyProperties> 
            <includeOnlyProperty>git.branch</includeOnlyProperty> 
            <includeOnlyProperty>git.build.time</includeOnlyProperty> 
            <includeOnlyProperty>git.build.version</includeOnlyProperty> 
            <includeOnlyProperty>git.commit.id</includeOnlyProperty> 
            <includeOnlyProperty>git.commit.time</includeOnlyProperty> 
        </includeOnlyProperties> 
    </configuration> 
</plugin>

Cela nous donne la possibilité de configurer de nombreuses options en fonction de nos besoins et nous pouvons inclure les propriétés. Actuellement, nous n’avons pris en compte que la branche git qui nous aidera à identifier le nom de la branche, le temps nécessaire pour terminer le processus de construction, la version de construction de git, l’ID de validation et l’horodatage de la validation exacte.

Puisque le fichier sera créé sous src/main/resources, nous voulons nous assurer que l’entrée resources est ajoutée dans la section build. Sinon, nous devons nous assurer que l’entrée suivante existe.

<resources> 
    <resource> 
        <directory>src/main/resources</directory> 
        <filtering>true</filtering> 
    </resource> 
</resources>

Maintenant laissers créer une classe de bean représentant notre Informations sur la construction.

@Data 
public class BuildInformation { 
 
    @SerializedName("git.branch") 
    private String branch; 
 
    @SerializedName("git.build.time") 
    private String buildTime; 
 
    @SerializedName("git.build.version") 
    private String buildVersion; 
 
    @SerializedName("git.commit.id") 
    private String commitId; 
 
    @SerializedName("git.commit.id.abbrev") 
    private String commitIdAbbrev; 
 
    @SerializedName("git.commit.id.describe") 
    private String commitIdDescribe; 
 
    @SerializedName("git.commit.id.describe-short") 
    private String commitIdDescribeShort; 
 
    @SerializedName("git.commit.time") 
    private String commitTime; 
 
    private String aemVersion; 
 
    private List<String> runModes; 
 
}

Notre interface de service ressemblera à ce:

public interface BuildInformationService { 
    BuildInformation getBuildInformation(); 
}

Enfin, notre classe d’implémentation ressemblera à comme ça:

@Component(service = BuildInformationService.class) 
@ServiceDescription("BuildInformationService Implementation.") 
@Slf4j 
public class BuildInformationServiceImpl implements BuildInformationService { 
 
    @Reference 
    private ProductInfoProvider productInfoProvider; 
 
    @Reference 
    private SlingSettingsService slingSettingsService; 
 
    public static final String GIT_INFO_FILE_PATH = "my-project-git-response.json"; 
 
    private BuildInformation buildInformation; 
 
    @Activate 
    public void activate() { 
 
        buildInformation = new BuildInformation(); 
        try { 
            final var inputStream = this.getClass().getClassLoader().getResourceAsStream(GIT_INFO_FILE_PATH); 
            final var jsonString = IOUtils.toString(inputStream, StandardCharsets.UTF_8); 
            final var gson = new Gson(); 
            buildInformation = gson.fromJson(jsonString, BuildInformation.class); 
 
            var productInfo = productInfoProvider.getProductInfo(); 
            final var version = productInfo.getVersion().toString(); 
            // Set additional fields not part of JSON response 
            buildInformation.setAemVersion(version); 
            buildInformation.setRunModes(slingSettingsService.getRunModes()); 
        } catch (Exception e) { 
            log.error("Error while generating build information"); 
        } 
    } 
 
    @Override 
    public BuildInformation getBuildInformation() { 
        return buildInformation; 
    } 
}

Nous lisons simplement le fichier de propriétés créé par le plugin et configurons l’objet.

L’API du fournisseur ProductInfo aidera à obtenir la version AEM tandis que le service de configuration Sling fournit des informations sur les modes d’exécution.

Créons maintenant un exemple de servlet qui utilisera ce service et imprimera les informations.

import com.google.gson.Gson; 
import org.apache.sling.api.SlingHttpServletRequest; 
import org.apache.sling.api.SlingHttpServletResponse; 
import org.apache.sling.api.servlets.SlingSafeMethodsServlet; 
import org.apache.sling.servlets.annotations.SlingServletPaths; 
import org.osgi.service.component.annotations.Component; 
import org.osgi.service.component.annotations.Reference; 
import org.osgi.service.component.propertytypes.ServiceDescription; 
 
import javax.servlet.Servlet; 
import javax.servlet.ServletException; 
import java.io.IOException; 
 
@Component(service = Servlet.class) 
@ServiceDescription("This servlet will provide Build Information") 
@SlingServletPaths(BuildInformationServlet.BUILD_INFO_PATH) 
public class BuildInformationServlet extends SlingSafeMethodsServlet { 
 
    public static final String BUILD_INFO_PATH = "/bin/my-project/buildinfo"; 
 
    @Reference 
    private BuildInformationService buildInformationService; 
 
    @Override 
    protected void doGet(final SlingHttpServletRequest request,final SlingHttpServletResponse response) 
            throws ServletException, IOException { 
        response.setContentType("application/json"); 
        response.setCharacterEncoding("UTF-8"); 
        final var writer = response.getWriter(); 
        final var gson = new Gson(); 
        final var jsonString = gson.toJson(buildInformationService.getBuildInformation()); 
        writer.print(jsonString); 
        writer.flush(); 
    } 
} 

Après avoir déployé le code et ouvert le point final du service, il donnera une réponse comme ce:

{ 

  "git.branch": "feature/PROJECT-1234", 

  "git.build.time": "2024-04-03-09-37", 

  "git.build.version": "2.22.0-65-SNAPSHOT", 

  "git.commit.id": "1fa29afb73e5b0cbfc90a2bb33db28741d98eec0", 

  "git.commit.id.abbrev": "1fa29af", 

  "git.commit.id.describe": "1fa29af-dirty", 

  "git.commit.id.describe-short": "1fa29af-dirty", 

  "git.commit.time": "2024-04-01-18-04", 

  "aemVersion": "6.5.17.0", 

  "runModes": [ 

    "s7connect", 

    "crx3", 

    "author", 

    "samplecontent", 

    "crx3tar" 

  ] 

}

Maintenant que notre service est opérationnel, nous pouvons l’exploiter n’importe où dans notre application. Créons un composant réutilisable pour afficher les informations de construction, alimenté par notre fidèle modèle Sling. Ce composant peut accéder au service pour récupérer les détails de construction nécessaires.

Comment inclure des détails de construction supplémentaires

Vous souhaitez inclure des détails de build supplémentaires, tels que les noms de tâches Jenkins et les numéros de build ? Facile! Nous pouvons transmettre ces attributs depuis Jenkins via des arguments de ligne de commande. Ensuite, nous stockons ces valeurs dans des fichiers de propriétés, les rendant facilement consommables par notre modèle Sling, tout comme notre fichier d’informations Git.

L’avantage de cette solution est qu’elle est flexible, évolutive et réutilisable sur plusieurs projets dans un environnement de développement mutualisé.

Assurez-vous de suivez notre blog Adobe pour plus de trucs et astuces sur les solutions Adobe !






Source link