Skip to content

Build and release #1409

Build and release

Build and release #1409

Workflow file for this run

name: Build and release
on:
workflow_dispatch:
push:
branches:
- '**'
env:
native_image_opts: --verbose -H:Log=registerResource:verbose -H:+PrintClassInitialization
graal_distribution: graalvm-community
graal_java_version: 17
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check-out source code
uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: PROD - Prepare GitHub release
id: create_prod_release
uses: GoogleCloudPlatform/release-please-action@v3
if: github.ref == 'refs/heads/main'
with:
command: github-release
release-type: simple
package-name: ${{ github.event.repository.name }}
default-branch: main
- name: PROD - Define release info
if: steps.create_prod_release.outputs.release_created
run: |
tag=${{steps.create_prod_release.outputs.tag_name}}
version=${{steps.create_prod_release.outputs.version}}
major=${{steps.create_prod_release.outputs.major}}
minor=${{steps.create_prod_release.outputs.minor}}
patch=${{steps.create_prod_release.outputs.patch}}
echo DO_BUILD=true >> $GITHUB_ENV
echo DO_RELEASE=true >> $GITHUB_ENV
echo DO_PROD_RELEASE=true >> $GITHUB_ENV
echo RELEASE_TAG=${tag} >> $GITHUB_ENV
echo RELEASE_VERSION=${version} >> $GITHUB_ENV
- name: DEV - Define release info
if: startsWith(github.ref, 'refs/heads/') && !env.DO_PROD_RELEASE
run: |
branch="${GITHUB_REF#refs/heads/}"
tag="dev_${branch//[^a-zA-Z0-9_.-]/.}" # Replace all special characters by a dot
version="0.$(date +'%Y%m%d.%H%M%S')-${tag}"
echo DO_BUILD=true >> $GITHUB_ENV # We always want to do a build if we're building a branch
echo BRANCH=${branch} >> $GITHUB_ENV
echo RELEASE_TAG=${tag} >> $GITHUB_ENV
echo RELEASE_VERSION=${version} >> $GITHUB_ENV
if git ls-remote --exit-code origin refs/tags/${tag} >/dev/null 2>&1; then
echo "Found tag ${tag}, development release will be published"
echo DO_RELEASE=true >> $GITHUB_ENV
echo DO_DEV_RELEASE=true >> $GITHUB_ENV
else
echo "Tag ${tag} does not exist, no development release will be published"
fi
- name: Build release ${{env.RELEASE_VERSION}}
if: env.DO_BUILD
run: ./gradlew clean build dist distThirdPartyReleaseAsset distFtest -Pversion=${{env.RELEASE_VERSION}}
- name: Check fcli version
if: env.DO_BUILD
run: java -jar build/libs/fcli.jar --version | tee /dev/stderr | grep -E '[0-9]+\.[0-9]+\.[0-9]+' >/dev/null || (echo "fcli --version doesn't output proper version number"; exit 1)
- name: Publish build artifacts
uses: actions/upload-artifact@v3
with:
path: build/dist/**/*
outputs:
do_release: ${{ env.DO_RELEASE }}
do_dev_release: ${{ env.DO_DEV_RELEASE }}
release_tag: ${{ env.RELEASE_TAG }}
native_linux:
name: native-image-linux
needs: build
runs-on: ubuntu-22.04
# env:
# TOOLCHAIN_BASE: /opt/musl_cc
# TOOLCHAIN_DIR: /opt/musl_cc/x86_64-linux-musl-native
# CC: /opt/musl_cc/x86_64-linux-musl-native/bin/gcc
steps:
- name: Check-out source code
uses: actions/checkout@v3
- uses: graalvm/setup-graalvm@v1
with:
distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
native-image-musl: true
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
with:
path: ./
# For Linux, we build a statically linked native image, to allow for building a 'FROM scratch'
# Docker image, and to avoid libc version issues. Since Jansi is not supported on statically
# linked images (see https://github.com/fusesource/jansi/issues/246), we set a system property
# to indicate that FortifyCLI shouldn't try to invoke AnsiConsole::systemInstall/Uninstall. In
# order for FortifyCLI to be able to see this system property, we need to initialize this class
# at build time (see https://www.graalvm.org/22.1/reference-manual/native-image/Properties/).
# We also exclude the native Jansi library resources, as these are now no longer needed.
- name: Create native fcli
run: native-image ${{ env.native_image_opts }} --static --libc=musl -Djansi.disable=true --initialize-at-build-time=com.fortify.cli.app.FortifyCLI -H:ExcludeResources="org/fusesource/jansi/internal/native/.*" -jar ./artifact/release-assets/fcli.jar fcli
- name: Compress native fcli
uses: svenstaro/upx-action@v2
with:
files: fcli
- name: Basic test of native fcli
run: ./fcli --help && ./fcli get --help
- name: Check fcli version
run: ./fcli --version | tee /dev/stderr | grep -E '[0-9]+\.[0-9]+\.[0-9]+' >/dev/null || (echo "fcli --version doesn't output proper version number"; exit 1)
- name: Package native fcli
run: tar -zcvf artifact/release-assets/fcli-linux.tgz fcli -C ./artifact fcli_completion
- uses: actions/upload-artifact@v3
with:
path: ./artifact/**/fcli-linux.tgz
native_mac:
name: native-image-mac
needs: build
runs-on: macos-12
steps:
- name: Check-out source code
uses: actions/checkout@v3
- uses: graalvm/setup-graalvm@v1
with:
distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
with:
path: ./
# For MacOS, we build a dynamically linked image. Jansi by default provides a resource-config.json
# file to include native libraries for all platforms; we override this to include only the MacOS
# libraries
- name: Create native fcli
run: native-image ${{ env.native_image_opts }} -H:ExcludeResources="org/fusesource/jansi/internal/native/Windows/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar ./artifact/release-assets/fcli.jar fcli
- name: Compress native fcli
uses: svenstaro/upx-action@v2
with:
files: fcli
- name: Basic test of native fcli
run: ./fcli --help && ./fcli get --help
- name: Package native fcli
run: tar -zcvf ./artifact/release-assets/fcli-mac.tgz fcli -C ./artifact fcli_completion
- uses: actions/upload-artifact@v3
with:
path: ./artifact/**/fcli-mac.tgz
native_win:
name: native-image-win
needs: build
runs-on: windows-2022
steps:
- uses: graalvm/setup-graalvm@v1
with:
distribution: ${{ env.graal_distribution }}
java-version: ${{ env.graal_java_version }}
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
with:
path: ./
# For Windows, we build a dynamically linked image. Jansi by default provides a resource-config.json
# file to include native libraries for all platforms; we override this to include only the 64-bit
# Windows library
- name: Create native fcli
run: >-
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" &&
${{ env.JAVA_HOME }}\bin\native-image.cmd ${{ env.native_image_opts }} -H:ExcludeResources="org/fusesource/jansi/internal/native/Mac/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/Linux/.*" -H:ExcludeResources="org/fusesource/jansi/internal/native/FreeBSD/.*" -jar .\artifact\release-assets\fcli.jar fcli
shell: cmd
# We don't compress the Windows binary for now as this is incompatible with current Graal version.
# See https://github.com/fortify/fcli/issues/148
# - name: Compress native fcli
# uses: svenstaro/upx-action@v2
# with:
# files: fcli.exe
- name: Basic test of native fcli
run: |
.\fcli.exe --help
.\fcli.exe get --help
- name: Package native fcli
run: 7z a artifact\release-assets\fcli-windows.zip fcli*.exe
- uses: actions/upload-artifact@v3
with:
path: ./artifact/**/fcli-windows.zip
release:
name: release
if: needs.build.outputs.do_release
needs: [build, native_linux, native_mac, native_win]
runs-on: ubuntu-latest
steps:
- name: Check-out source code
uses: actions/checkout@v3
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ./
- name: PROD - Prepare release PR
if: github.ref == 'refs/heads/main'
uses: GoogleCloudPlatform/release-please-action@v3
with:
command: release-pr
release-type: simple
package-name: ${{ github.event.repository.name }}
default-branch: main
- name: DEV - Prepare GitHub release
if: needs.build.outputs.do_dev_release
run: |
gh release delete ${{ needs.build.outputs.release_tag }} -y || true
gh release create ${{ needs.build.outputs.release_tag }} -p -t "Development Release - ${GITHUB_REF#refs/heads/} branch" -n 'See `Assets` section below for latest build artifacts'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: DEV - Update ${{ needs.build.outputs.release_tag }} tag
uses: richardsimko/update-tag@v1
if: needs.build.outputs.do_dev_release
with:
tag_name: ${{ needs.build.outputs.release_tag }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload assets to release
if: needs.build.outputs.do_release
run: |
files=$(find "./artifact/release-assets" -type f -printf "%p ")
gh release upload "${{ needs.build.outputs.release_tag }}" $files --clobber
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publishPages:
name: publishPages
if: needs.build.outputs.do_release
needs: [build, release]
runs-on: ubuntu-latest
steps:
- name: Check-out existing docs from gh-pages branch
uses: actions/checkout@v3
with:
ref: gh-pages
path: docs
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ./
- name: Update documentation from artifact
run: |
# Delete all Git-related files
rm -rf docs/.git*
# Extract top-level documentation resources
# TODO Should we do this only when building a release, or also for dev_main,
# or for all (dev & release) versions like we do now?
unzip -o artifact/docs-gh-pages.zip -d "docs"
# Define the output directory, based on tag/branch name
versionDir=docs/${{ needs.build.outputs.release_tag }}
# Delete, recreate and fill the directory for the current tag/branch name,
# while leaving documentation for other tags/branches intact (as checked out above)
rm -rf "${versionDir}"
mkdir -p "${versionDir}"
unzip artifact/docs-jekyll.zip -d "${versionDir}"
# Recreate version data files, which may be empty if no versions available
cd docs
mkdir -p _data/versions
touch _data/versions/release.yml
touch _data/versions/dev.yml
ls -d v*.*.* | sort -rV | while read line; do echo "- '$line'"; done > _data/versions/release.yml
ls -d dev_* | sort | while read line; do echo "- '$line'"; done > _data/versions/dev.yml
- name: Deploy documentation
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
enable_jekyll: true