Création d'un pipeline pour fournir Graal Native Image aux utilisateurs finaux

Dans cet article, je veux décrire mon expérience dans la livraison de Graal Native Image aux utilisateurs finaux de Mac OS et Linux en une seule commande à l'aide de Travis CI.


Lorsque j'ai rencontré ce problème, j'ai ressenti un manque d'informations sur ce sujet, j'ai donc décidé de décrire mon expérience ici.


Commençons.


J'ai:


  • Application Java avec toutes les configurations pour créer une image native.

Ce que je veux obtenir:


  • Créez une image native avec Travis
  • Construire des distributions rpm et deb, ainsi qu'une archive pour la version mac
  • Versez les paquets reçus sur Bintray
  • Donner aux utilisateurs la possibilité de télécharger l'application via le gestionnaire de packages
  • Automatisez le processus autant que possible.

Aller


Tout d'abord, créez un monde Hello simple.


package release.test;

public class Application {

    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

Et ajoutez des plugins de base à pom.xml.


 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
            </plugin>
            <plugin>
                <!-- Build an executable JAR -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>release.test.Application</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <version>2.5.3</version>
                <configuration>
                    <tagNameFormat>${project.version}</tagNameFormat>
                </configuration>
            </plugin>
        </plugins>
    </build>

Ensuite, je vais créer deux profils pour construire respectivement mac et linux. Je vais l'utiliser maven-assembly-plugin. Je n'obstruerai pas l'article avec des tonnes de xml, au lieu de cela j'attacherai un lien avec un exemple complet.


Passons à Travis CI. C'est là que je veux créer une image native, l'emballer dans les bons packages et la déployer.


Nous allons créer un fichier .travis.ymlpour décrire le plan de déploiement et nous le remplirons progressivement.
Pour commencer, cela ressemblera à ceci:


os:
 - linux
 - osx

language: java
install: true

script:
 - if [ $TRAVIS_OS_NAME == "osx" ]; then
    chmod +x ./prepare-mac.sh;
    ./prepare-mac.sh;
   fi
 - if [ $TRAVIS_OS_NAME == "linux" ]; then
    chmod +x ./prepare-linux.sh;
    ./prepare-linux.sh;
   fi

, . .


Mac OS :


#!/usr/bin/env bash
curl -OL https://github.com/oracle/graal/releases/download/vm-19.1.1/graalvm-ce-darwin-amd64-19.1.1.tar.gz
tar zxf graalvm-ce-darwin-amd64-19.1.1.tar.gz
sudo mv graalvm-ce-19.1.1 /Library/Java/JavaVirtualMachines
export PATH=/Library/Java/JavaVirtualMachines/graalvm-ce-19.1.1/Contents/Home/bin:$PATH
/Library/Java/JavaVirtualMachines/graalvm-ce-19.1.1/Contents/Home/bin/gu install native-image
mvn clean package -P mac
NAME=$(basename $(find . -type f -name 'release-test-*.jar'))
native-image -jar target/${NAME} -H:Name=release-test
mvn package -P assembly

. , GraalVM, native-image, Graal Mac. , jar, native-image , .


Linux , rpm deb :


#!/usr/bin/env bash
curl -OL https://github.com/oracle/graal/releases/download/vm-19.1.1/graalvm-ce-linux-amd64-19.1.1.tar.gz
tar zxf graalvm-ce-linux-amd64-19.1.1.tar.gz
sudo mv graalvm-ce-19.1.1 /usr/lib/jvm/
export JAVA_HOME=/usr/lib/jvm/graalvm-ce-19.1.1
export PATH=$PATH:${JAVA_HOME}/bin

mvn clean install
${JAVA_HOME}/bin/gu install native-image
NAME=$(basename $(find . -type f -name 'release-test-*.jar'))

mkdir release-deb
cd release-deb
native-image -jar ../target/${NAME} -H:Name=release-test
PACK_NAME=$(ls)
chmod +x ${PACK_NAME}
mkdir packageroot
mkdir packageroot/DEBIAN
touch packageroot/DEBIAN/control
VERSION=$(echo "${NAME%.*}" | cut -d'-' -f 3)
echo "Package: $PACK_NAME
Version: $VERSION
Architecture: amd64
Maintainer: John Doe <john@doe.com>
Description: test
" > packageroot/DEBIAN/control
cat packageroot/DEBIAN/control
mkdir -p packageroot/usr/bin
cp ${PACK_NAME} packageroot/usr/bin/
dpkg-deb -b packageroot ${PACK_NAME}-${VERSION}.deb

sudo dpkg -i ./${PACK_NAME}-${VERSION}.deb
sudo apt-get install -f

DEB_PACK=$(find . -type f -name 'release-test-*.deb')
echo ${DEB_PACK}
cp ${DEB_PACK} ../target/

cd ../target

# convert to rpm
sudo apt-get update
sudo apt-get install rpm
sudo apt-get install ruby ruby-dev rubygems build-essential
gem install --no-ri --no-rdoc fpm

fpm -t rpm -s deb ${PACK_NAME}-${VERSION}.deb

GraalVM native-image. , , .


debian . , , .


mkdir release-deb
cd release-deb
native-image -jar ../target/${NAME} -H:Name=release-test
PACK_NAME=$(ls)
chmod +x ${PACK_NAME}
mkdir packageroot
mkdir packageroot/DEBIAN
touch packageroot/DEBIAN/control
VERSION=$(echo "${NAME%.*}" | cut -d'-' -f 3)
echo "Package: $PACK_NAME
Version: $VERSION
Architecture: amd64
Maintainer: John Doe <john@doe.com>
Description: test
" > packageroot/DEBIAN/control
cat packageroot/DEBIAN/control
mkdir -p packageroot/usr/bin
cp ${PACK_NAME} packageroot/usr/bin/
dpkg-deb -b packageroot ${PACK_NAME}-${VERSION}.deb

sudo dpkg -i ./${PACK_NAME}-${VERSION}.deb
sudo apt-get install -f

DEB_PACK=$(find . -type f -name 'release-test-*.deb')
echo ${DEB_PACK}
cp ${DEB_PACK} ../target/

debian rpm. , fpm. rpm debian.


# convert to rpm
sudo apt-get update
sudo apt-get install rpm
sudo apt-get install ruby ruby-dev rubygems build-essential
gem install --no-ri --no-rdoc fpm

fpm -t rpm -s deb ${PACK_NAME}-${VERSION}.deb

before_deploy .travis.yml, .


before_deploy:
  - if [ $TRAVIS_OS_NAME == "linux" ]; then
    chmod +x ./update-version.sh;
    ./update-version.sh;
    fi

update-version.sh


#!/usr/bin/env bash

cd target

NAME=$(basename $(find . -type f -name 'release-test-*.jar'))
VERSION=$(echo "${NAME%.*}" | cut -d'-' -f 3)

cd ../

sed -i "s/template_version/$VERSION/g" deploy-deb.json
sed -i "s/template_tag/$VERSION/g" deploy-deb.json

sed -i "s/template_version/$VERSION/g" deploy-rpm.json
sed -i "s/template_tag/$VERSION/g" deploy-rpm.json

deploy-deb.json deploy-rpm.json — bintray. . , . update-version.sh json .


. bintray . generic, rpm debian bintray. , master-. mac Rest API. Rest API Bintray . linux bintray provider, Travis CI.


deploy:
  - provider: script
    skip_cleanup: true
    script:
      cd target;
      curl -X PUT -H X-GPG-PASSPHRASE:$PASSPHRASE_BINTRAY --basic -u aarrsseni:$BINTRAY_API_KEY https://api.bintray.com/content/aarrsseni/release-test/release-test/$TRAVIS_TAG/release-test-$TRAVIS_TAG.zip?publish=1
    on:
      branch: master
      condition: $TRAVIS_OS_NAME == "osx"
      tags: true
  - provider: bintray
    file: deploy-deb.json
    user: aarrsseni
    key:
      secure: your_key
    passphrase:
      secure: your_passphrase
    skip_cleanup: true
    on:
      branch: master
      condition: $TRAVIS_OS_NAME == "linux"
      tags: true
  - provider: bintray
    file: deploy-rpm.json
    user: aarrsseni
    key:
      secure: your_key
    passphrase:
      secure: your_passphrase
    skip_cleanup: true
    on:
      branch: master
      condition: $TRAVIS_OS_NAME == "linux"
      tags: true

zip , rpm deb , bintray.
rpm deb apt-get yum.


mac brew . . , . .


brew Formula. release-test.rb. zip bintray, , .


class ReleaseTest < Formula
  desc "Your desc"
  homepage "your website"
  url "https://bintray.com/aarrsseni/release-test/download_file?file_path=release-test-1.70.zip"
  sha256 "84b09c9c1c45ef0b040811be58c9f14cf8ef7237139f0a8483ccd85c6ea1bb64"

  bottle :unneeded

  def install
    libexec.install Dir["*"]
    bin.install_symlink libexec/"bin/release-test"
  end

  test do
    system "release-test"
  end
end

, .travis.yml after_deploy.


after_deploy:
 - if [ $TRAVIS_OS_NAME == "osx" ]; then
  chmod +x ./update-homebrew.sh;
  ./update-homebrew.sh;
  fi

update-homebrew.sh brew , , .


#!/usr/bin/env bash
NAME=$(basename $(find . -type f -name 'release-test-*.zip'))
echo ${NAME}
mkdir temp-homebrew

CHECKSUM=$(echo "$(shasum -a 256 target/${NAME})" | awk '{print $1;}')
echo ${CHECKSUM}

cd temp-homebrew
git clone https://github.com/aarrsseni/homebrew-test-release
cd homebrew-test-release
git remote add origin-deploy https://${GITHUB_TOKEN}@github.com/aarrsseni/homebrew-test-release.git
cd Formula

cat release-test.rb

PREV_NAME=$(grep -o 'file_path=.*$' release-test.rb | cut -c11-)
PREV_NAME=${PREV_NAME%?}

PREV_CHECKSUM_FROM_FILE=$(grep -o 'sha256.*$' release-test.rb | cut -c9-)
PREV_CHECKSUM=${PREV_CHECKSUM_FROM_FILE%?}

echo ${PREV_NAME}
echo ${PREV_CHECKSUM}

sed -i '.bak' "s/$PREV_NAME/$NAME/g" release-test.rb

sed -i '.bak' "s/$PREV_CHECKSUM/$CHECKSUM/g" release-test.rb

cat release-test.rb

git add .
git commit -m "Update formula version"
git push origin-deploy master

, mac , brew install USERNAME/REPO_NAME/TOOL_NAME, USERNAME — github, REPO_NAME — , TOOL_NAME — .


, github bintray .travis.yml .



mvn release:prepare native image mac linux, .



homebrew


All Articles