En este artículo, quiero describir mi experiencia en la entrega de Graal Native Image a usuarios finales de Mac OS y Linux en un comando usando Travis CI.
Cuando me encontré con este problema, sentí una falta de información sobre este tema, así que decidí describir mi experiencia aquí.
Empecemos.
Yo tengo:
- Aplicación Java con todas las configuraciones para construir imágenes nativas.
Lo que quiero obtener:
- Construye una imagen nativa con Travis
- Cree distribuciones rpm y deb, así como un archivo para la versión mac
- Vierta los paquetes recibidos en Bintray
- Ofrezca a los usuarios la posibilidad de descargar la aplicación a través del administrador de paquetes
- Automatice el proceso tanto como sea posible.
Vamos
Primero, crea un simple Hello world.
package release.test;
public class Application {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Y agregue complementos base a pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<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>
A continuación, crearé dos perfiles para construir mac y linux, respectivamente. Lo voy a utilizar maven-assembly-plugin
. No obstruiré el artículo con toneladas de xml, en su lugar adjuntaré un enlace con un ejemplo completo.
Pasemos a Travis CI. Aquí es donde quiero construir una imagen nativa, empaquetarla en los paquetes correctos e implementarla.
Crearemos un archivo .travis.yml
para describir el plan de implementación y lo llenaremos gradualmente.
Para comenzar, se verá así:
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