Search code examples
mavenansiblejenkins-pipelinenexus

How can I fix maven_artifact ZIP download task in Ansible?


I have two Jenkins pipelines. The first one is building a project with Maven.
One of the plugins creates a ZIP of some scripts.

Here is the pom.xml part

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
        <execution>
            <id>script</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <finalName>script-${project.version}</finalName>
                <appendAssemblyId>true</appendAssemblyId>
                <descriptors>
                    <descriptor>src/main/assembly/script.xml</descriptor>
                </descriptors>
            </configuration>
        </execution>
    </executions>
</plugin>

The script.xml specify the directory to ZIP and files to exclude

<formats>
    <format>zip</format>
</formats>
<fileSets>
    <fileSet>
        <directory>${project.basedir}/src/scripts</directory>
        <filtered>true</filtered>
        <directoryMode>755</directoryMode>
        <fileMode>755</fileMode>
         <lineEnding>unix</lineEnding>
        <outputDirectory></outputDirectory>
        <excludes>
            <exclude>
            **/*.log
            </exclude>
        </excludes>
    </fileSet>
</fileSets>

At the end of the build, the artifactPublisher publish the ZIP to a Nexus repository with a mvn deploy.
Here is the log:

[withMaven] artifactsPublisher - Archive artifact target/checkout/target/script-2.0.0-script.zip under com/company/artifact_id/2.0.0/artifact_id-2.0.0-script.zip

Now I have a deploy pipeline that needs to download this artifact with Ansible.
Here is the task to the download the ZIP

- maven_artifact:
    group_id: "{{maven_grpid}}"
    artifact_id: artifact_id
    extension: zip
    version: "{{ zip_version }}"
    repository_url: "{{ nexus_repo }}"
    username: "{{ nexus_user }}"
    password: "{{ nexus_password }}"
    dest: '{{ install_path }}/script/artifact_id-{{ zip_version }}-script.tmp'
    verify_checksum: change
    mode: '0770'
    validate_certs: false
  become: yes

This fails because it doesn't build the correct URL to the ZIP file

Failed to download artifact com.company:artifact_id:zip:2.0.0 because of HTTP Error 404: com/company/artifact_id/2.0.0/artifact_id-2.0.0.zipfor URL https://nexus_url/repository/maven-releases/com/company/artifact_id/2.0.0/artifact_id-2.0.0.zip

The correct url of the file is:

https://nexus_url/repository/maven-releases/com/company/artifact_id/2.0.0/artifact_id-2.0.0-script.zip

as shown in the artifactPublisher part.

I tried tweaking the version in Ansible with {{ zip_version }}-script, the filename is, then, correct, but the version in the URL gets messed up with it.

How do I fix that? Can I tweak the filename in the Ansible task? Or maybe there is a way to change the artifact name that is published?


Solution

  • The good thing with Ansible being an open sourced tool is the fact that you can have a peak at the code.

    In this case, the file representing this module can be found in the community.general collection repository.

    With this, we can now find the way Ansible it building the URL in the method _uri_for_artifact.
    And this is probably the most interesting lines of the said method for your use case:

    if artifact.classifier:
        return posixpath.join(self.base, artifact.path(), artifact.artifact_id + "-" + version + "-" + artifact.classifier + "." + artifact.extension)
    

    Going back to the documentation, we can see that you just have to specify a classifier to be build in your URL.

    So your missing part is

    classifier: script
    

    Which lead you to a task being

    - maven_artifact:
        group_id: "{{ maven_grpid }}"
        artifact_id: artifact_id
        classifier: script
        extension: zip
        version: "{{ zip_version }}"
        repository_url: "{{ nexus_repo }}"
        username: "{{ nexus_user }}"
        password: "{{ nexus_password }}"
        dest: '{{ install_path }}/script/artifact_id-{{ zip_version }}-script.tmp'
        verify_checksum: change
        mode: '0770'
        validate_certs: false
      become: yes