Skip to content

Build and publish asvec #138

Build and publish asvec

Build and publish asvec #138

name: Build asvec
on:
push:
branches:
- main
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'If this is a release what version is this for? If this is a pre-release what version are you developing toward?'
required: true
type: string
preRelease:
description: 'Create Pre-release? -SNAPSHOT-{COMMIT} will be appended to the version above.'
required: false
type: boolean
deletePrevBuild:
description: 'Cleanup existing pre-releases?'
required: false
type: boolean
env:
JFROG_CLI_BUILD_NAME: 'asvec'
JFROG_CLI_LOG_LEVEL: DEBUG
JFROG_CLI_BUILD_PROJECT: 'ecosystem'
ARTIFACT_NAME: 'asvec'
jobs:
build:
outputs:
version: ${{ steps.parse-version.outputs.version }}
is-snapshot: ${{ steps.parse-version.outputs.is-snapshot }}
rpm-version: ${{ steps.save-version.outputs.rpm-version }}
artifacts: ${{ steps.save-version.outputs.artifacts }}
rpm-artifacts: ${{ steps.save-version.outputs.rpm-artifacts }}
deb-artifacts: ${{ steps.save-version.outputs.deb-artifacts }}
zip-artifacts: ${{ steps.save-version.outputs.zip-artifacts }}
pkg-artifacts: ${{ steps.save-version.outputs.pkg-artifacts }}
sha-artifacts: ${{ steps.save-version.outputs.sha-artifacts }}
asc-artifacts: ${{ steps.save-version.outputs.asc-artifacts }}
runs-on: macos-13
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Extract Version and Snapshot'
id: parse-version
run: |
# Default to version from workflow_dispatch or tag
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Manual build: Use version input
TAG="${{ inputs.version }}"
echo "Triggered manually with version: ${TAG}"
elif [[ "${{ github.event_name }}" == "push" ]]; then
# Push event: Extract tag from GITHUB_REF
TAG=${GITHUB_REF#refs/tags/}
echo "Triggered by push with tag: ${TAG}"
else
echo "Unsupported event: ${{ github.event_name }}"
exit 1
fi
# Remove "v" prefix to get the version
VERSION=${TAG#v}
# Check if it's a snapshot
if [[ "$VERSION" == *-SNAPSHOT-* ]]; then
SNAPSHOT="true"
elif [[ ${{ inputs.preRelease }} == true ]]; then
SNAPSHOT="true"
COMMIT=$(git rev-parse --short HEAD)
VERSION="${VERSION}-SNAPSHOT-${COMMIT}"
else
SNAPSHOT="false"
fi
# Output the results
echo "VERSION=${VERSION}" >> $GITHUB_ENV
echo "SNAPSHOT=${SNAPSHOT}" >> $GITHUB_ENV
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "is-snapshot=${SNAPSHOT}" >> $GITHUB_OUTPUT
echo "Version: ${VERSION} Snapshot: ${SNAPSHOT} version=${VERSION} is-snapshot=${SNAPSHOT}"
- name: setup jfrog
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: https://aerospike.jfrog.io
JF_ACCESS_TOKEN: ${{ secrets.JFROG_ACCESS_TOKEN }}
JF_PROJECT: ${{ env.JFROG_CLI_BUILD_PROJECT }}
# Enable when we can use jf from makefiles differentiating between deb, rpm, pkg etc.
# Each of those types should be in a different jfrog build. Also will need to run go-setup.sh before build steps are called.
# - name: 'Alias go to jf go'
# run: |
# # This will set up jf go build instead of go build. This lets us also include build number and build name
# # for jfrog builds.
# # Write the function to a script using a heredoc
# cat << EOF > ~/go-setup.sh
# #!/bin/bash
# go() {
# if [[ "\$1" == "build" ]]; then
# shift
# jf go build --build-name=$JFROG_CLI_BUILD_NAME --build-number=$VERSION --project=$JFROG_CLI_BUILD_PROJECT "\$@"
# else
# command go "\$@"
# fi
# }
# EOF
# chmod +x ~/go-setup.sh
- name: 'Install Homebrew'
run: /bin/bash -c "NONINTERACTIVE=1 $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- name: 'Install Dependencies'
run: |
/usr/local/bin/brew install --overwrite [email protected] || echo "I1.1"
/usr/local/bin/brew link --overwrite [email protected] || echo "I1.2"
/usr/local/bin/brew install --overwrite dpkg zip make wget jq rpm || echo "I2"
/usr/local/bin/brew link --overwrite [email protected] || echo "I1.3"
/usr/local/bin/brew install [email protected] || echo "I1.4"
/usr/local/bin/brew install [email protected] || echo "I1.5"
for i in dpkg zip make wget jq rpm python3.11; do command -v $i || exit 1; done
echo "Dependencies checked"
- name: Get go version from go.mod
run: |
echo "GO_VERSION=$(grep '^go ' go.mod | cut -d " " -f 2)" >> $GITHUB_ENV
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: 'Install Packages.pkg for making macos PKG files'
run: |
wget http://s.sudre.free.fr/Software/files/Packages.dmg
hdiutil attach -mountpoint /Volumes/Packages Packages.dmg
cd /Volumes/Packages
sudo installer -pkg Install\ Packages.pkg -target /
- name: 'Compile'
env:
ADDCOMMIT: ${{ steps.parse-version.outputs.is-snapshot }}
run: |
buildcmd="build-prerelease"
[ "${ADDCOMMIT}" = "false" ] && buildcmd="build-official"
export PATH=$PATH:/usr/local/bin:/usr/local/go/bin
cd ~/work/asvec/asvec && make cleanall && make ${buildcmd}
- name: 'Create linux packages'
env:
ADDCOMMIT: ${{ steps.parse-version.outputs.is-snapshot }}
run: |
buildcmd="build-prerelease"
[ "${ADDCOMMIT}" = "false" ] && buildcmd="build-official"
export PATH=$PATH:/usr/local/bin:/usr/local/go/bin
cd ~/work/asvec/asvec && make pkg-linux
- name: 'Create windows zips'
env:
ADDCOMMIT: ${{ steps.parse-version.outputs.is-snapshot }}
run: |
buildcmd="build-prerelease"
[ "${ADDCOMMIT}" = "false" ] && buildcmd="build-official"
export PATH=$PATH:/usr/local/bin:/usr/local/go/bin
cd ~/work/asvec/asvec && make pkg-windows-zip
- name: 'Print asvec version'
run: cd ~/work/asvec/asvec && ./bin/asvec-macos-amd64 --version
- name: 'Prepare keychain for signing MacOS'
env:
keypw: ${{ secrets.APPLEUSERPW }}
INSTALLERP12: ${{ secrets.INSTALLERP12 }}
APPLICATIONP12: ${{ secrets.APPLICATIONP12 }}
run: |
set -e
security create-keychain -p mysecretpassword build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p mysecretpassword build.keychain
security set-keychain-settings build.keychain
security unlock-keychain -p mysecretpassword build.keychain
echo "$APPLICATIONP12" | base64 -d > app.p12
echo "$INSTALLERP12" | base64 -d > install.p12
security import app.p12 -k build.keychain -P $keypw -A
security import install.p12 -k build.keychain -P $keypw -A
security set-key-partition-list -S apple-tool:,apple: -s -k mysecretpassword build.keychain
- name: 'Sign and build MacOS'
env:
xasvec_appleid: ${{ secrets.APPLEUSER }}
xasvec_applepw: ${{ secrets.APPLEAPPPW }}
xasvec_signer: ${{ secrets.APPLESIGNER }}
xasvec_installsigner: ${{ secrets.APPLEINSTALLSIGNER }}
xasvec_teamid: ${{ secrets.APPLETEAMID }}
run: |
set -e
export asvec_appleid="${xasvec_appleid}"
export asvec_applepw="${xasvec_applepw}"
export asvec_signer="${xasvec_signer}"
export asvec_installsigner="${xasvec_installsigner}"
export asvec_teamid="${xasvec_teamid}"
export PATH=$PATH:/usr/local/bin:/usr/local/go/bin && cd ~/work/asvec/asvec && make macos-build-all && make macos-notarize-all
- name: Save Version
id: save-version
run: |
VER=$(cat VERSION.md)
echo version=${VER} >> $GITHUB_OUTPUT
RPM_VER=$(echo ${VER} | sed 's/-/_/g')
echo rpm-version=${RPM_VER} >> $GITHUB_OUTPUT
ARTIFACTS="asvec-linux-amd64-${VER}.deb asvec-linux-amd64-${RPM_VER}.rpm asvec-linux-amd64-${VER}.zip asvec-linux-arm64-${VER}.deb asvec-linux-arm64-${RPM_VER}.rpm asvec-linux-arm64-${VER}.zip asvec-macos-${VER}.pkg asvec-macos-amd64-${VER}.zip asvec-macos-arm64-${VER}.zip asvec-windows-amd64-${VER}.zip asvec-windows-arm64-${VER}.zip"
echo "artifacts=${ARTIFACTS}" >> $GITHUB_OUTPUT
RPM_ARTIFACTS=$(echo "${ARTIFACTS}" | tr ' ' '\n' | grep '\.rpm$' | tr '\n' ' ')
echo "rpm-artifacts=${RPM_ARTIFACTS}" >> $GITHUB_OUTPUT
DEB_ARTIFACTS=$(echo "${ARTIFACTS}" | tr ' ' '\n' | grep '\.deb$' | tr '\n' ' ')
echo "deb-artifacts=${DEB_ARTIFACTS}" >> $GITHUB_OUTPUT
ZIP_ARTIFACTS=$(echo "${ARTIFACTS}" | tr ' ' '\n' | grep '\.zip$' | tr '\n' ' ')
echo "zip-artifacts=${ZIP_ARTIFACTS}" >> $GITHUB_OUTPUT
PKG_ARTIFACTS=$(echo "${ARTIFACTS}" | tr ' ' '\n' | grep '\.pkg$' | tr '\n' ' ')
echo "pkg-artifacts=${PKG_ARTIFACTS}" >> $GITHUB_OUTPUT
SHA256_FILES=$(for pkg in ${ARTIFACTS}; do echo "${pkg}.sha256"; done | tr '\n' ' ')
echo "sha-artifacts=${SHA256_FILES}" >> $GITHUB_OUTPUT
ASC_FILES=$(for pkg in ${ARTIFACTS} ${SHA256_FILES}; do
if [[ ! "${pkg}" =~ \.rpm$ && ! "${pkg}" =~ \.deb$ ]]; then
echo "${pkg}.asc"
fi
done | tr '\n' ' ')
echo "asc-artifacts=${ASC_FILES}" >> $GITHUB_OUTPUT
- name: 'Upload Artifacts'
uses: actions/upload-artifact@v4
with:
name: asvec-artifacts
path: ~/work/asvec/asvec/bin/packages/asvec-*
sign:
needs: build
runs-on: ubuntu-latest
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Download Artifacts'
uses: actions/download-artifact@v4
with:
name: asvec-artifacts
- name: setup GPG
uses: aerospike/shared-workflows/devops/setup-gpg@main
with:
gpg-private-key: ${{ secrets.GPG_SECRET_KEY }}
gpg-public-key: ${{ secrets.GPG_PUBLIC_KEY }}
gpg-key-pass: ${{ secrets.GPG_PASS }}
gpg-key-name: 'aerospike-inc'
- name: GPG Sign All Files
env:
GPG_TTY: no-tty
GPG_PASSPHRASE: ${{ secrets.GPG_PASS }}
run: |
rpm --addsign ${{needs.build.outputs.rpm-artifacts}}
rpm --checksig ${{needs.build.outputs.rpm-artifacts}}
dpkg-sig --sign builder ${{needs.build.outputs.deb-artifacts}}
dpkg-sig --verify ${{needs.build.outputs.deb-artifacts}}
for file in ${{needs.build.outputs.zip-artifacts}} ${{needs.build.outputs.pkg-artifacts}}; do
gpg --detach-sign --no-tty --batch --yes --output "${file}.asc" --passphrase "$GPG_PASSPHRASE" "${file}"
gpg --verify "${file}.asc" "${file}"
done
- name: Create Checksums
run: |
for pkg in ${{needs.build.outputs.artifacts}}; do
shasum -a 256 $pkg > ${pkg}.sha256
done
for file in ${{needs.build.outputs.sha-artifacts}}; do
gpg --detach-sign --no-tty --batch --yes --output "${file}.asc" --passphrase "$GPG_PASSPHRASE" "${file}"
gpg --verify "${file}.asc" "${file}"
done
- name: 'Upload Artifacts'
uses: actions/upload-artifact@v4
with:
name: asvec-artifacts
path: asvec-*
overwrite: true
pre-release:
needs:
- sign
- build
runs-on: ubuntu-latest
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Download Artifacts'
uses: actions/download-artifact@v4
with:
name: asvec-artifacts
- name: 'Create a new pre-release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
TAG=${{needs.build.outputs.version}}
FULLCOMMIT=$(git rev-parse HEAD)
gh release create -R github.com/aerospike/asvec --prerelease --target ${FULLCOMMIT} --title "Asvec - ${TAG}" ${TAG} ${{needs.build.outputs.artifacts}} ${{needs.build.outputs.sha-artifacts}} ${{needs.build.outputs.asc-artifacts}}
- name: 'Delete previous pre-release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DELPREV: ${{ inputs.deletePrevBuild }}
run: |
if [ "${DELPREV}" = "true" ]; then
set -e
gh release list -R github.com/aerospike/asvec -L 100 | grep Pre-release | awk -F'\t' '{print $3}' | while read -r line; do
if [ "$line" != "${{needs.build.outputs.version}}" ]; then
if [[ "$line" == "${{ inputs.version }}-SNAPSHOT-"* ]]; then
echo "Removing $line"
gh release delete "$line" -R github.com/aerospike/asvec --yes --cleanup-tag
fi
fi
done
fi
build-docker:
needs:
- sign
- build
runs-on: ubuntu-latest
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: all
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: setup jfrog
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: https://aerospike.jfrog.io
JF_ACCESS_TOKEN: ${{ secrets.JFROG_ACCESS_TOKEN }}
JF_PROJECT: ${{ env.JFROG_CLI_BUILD_PROJECT }}
- name: Login to Artifact Aerospike Docker Registry
run: |
jf docker login artifact.aerospike.io --username ${{ secrets.JFROG_USERNAME }} --password ${{ secrets.JFROG_ACCESS_TOKEN }}
env:
JFROG_CLI_OFFER_CONFIG: 'false'
- name: Configure JFrog CLI
run: |
jf c add \
--url https://artifact.aerospike.io/ \
--user ${{ secrets.JFROG_USERNAME }} \
--access-token ${{ secrets.JFROG_ACCESS_TOKEN }} \
artifact
jf c use artifact
env:
JFROG_CLI_OFFER_CONFIG: 'false'
- name: 'Download Artifacts'
uses: actions/download-artifact@v4
with:
name: asvec-artifacts
- name: setup jfrog
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: https://aerospike.jfrog.io
JF_ACCESS_TOKEN: ${{ secrets.JFROG_ACCESS_TOKEN }}
JF_PROJECT: ${{ env.JFROG_CLI_BUILD_PROJECT }}
- name: Build and Push Docker Image
run: |
jf docker buildx bake \
--set asvec.tags=artifact.aerospike.io/${{ env.JFROG_CLI_BUILD_PROJECT }}-container-dev-local/asvec:${{ needs.build.outputs.version }} \
--file docker/asvec.docker/bake.hcl \
--push \
--metadata-file=build-metadata
env:
DOCKER_BUILDKIT: '1'
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Extract Image Name and Digest
run: |
jq -r '.[] | {digest: .["containerimage.digest"], names: .["image.name"] | split(",")} | "(.digest)"' build-metadata > sha
echo artifact.aerospike.io/${{ env.JFROG_CLI_BUILD_PROJECT }}-container-dev-local/asvec:${{ needs.build.outputs.version }}@$(cat sha) > meta-info
echo artifact.aerospike.io/${{ env.JFROG_CLI_BUILD_PROJECT }}-container-dev-local/asvec:${{ needs.build.outputs.version }}@$(cat sha) > meta-info-latest
- name: Create Docker Build Info
run: |
jf rt build-docker-create \
--build-name "${{ env.JFROG_CLI_BUILD_NAME }}-container" \
--build-number "${{ needs.build.outputs.version }}" \
--image-file ./meta-info \
--project ${{env.JFROG_CLI_BUILD_PROJECT}} \
ecosystem-container-dev-local
- name: Publish Build Info
run: |
export JFROG_CLI_LOG_LEVEL=DEBUG
jf rt build-collect-env --project ecosystem "${{ env.JFROG_CLI_BUILD_NAME }}-container" "${{ needs.build.outputs.version }}"
jf rt build-add-git --project ecosystem "${{ env.JFROG_CLI_BUILD_NAME }}-container" "${{ needs.build.outputs.version }}"
jf rt build-publish \
--detailed-summary \
--project ecosystem \
"${{ env.JFROG_CLI_BUILD_NAME }}-container" "${{ needs.build.outputs.version }}"
publish-asvec-build:
needs:
- sign
- build
runs-on: ubuntu-latest
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Download Artifacts'
uses: actions/download-artifact@v4
with:
name: asvec-artifacts
- name: setup jfrog
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: https://aerospike.jfrog.io
JF_ACCESS_TOKEN: ${{ secrets.JFROG_ACCESS_TOKEN }}
JF_PROJECT: ${{ env.JFROG_CLI_BUILD_PROJECT }}
- name: "Upload deb builds to JFrog"
run: |
find .
for file in ${{needs.build.outputs.deb-artifacts}}; do
if [[ "$file" == *.deb ]]; then
arch=$(dpkg --info "$file" | grep 'Architecture' | awk '{print $2}')
jf rt upload "$file" "${{env.JFROG_CLI_BUILD_PROJECT}}-deb-dev-local/${{ env.ARTIFACT_NAME }}/${{ needs.build.outputs.version }}/" \
--build-name="${{ env.JFROG_CLI_BUILD_NAME }}-deb" --build-number="${{ needs.build.outputs.version }}" --project="${{env.JFROG_CLI_BUILD_PROJECT}}" \
--target-props "deb.distribution=stable;deb.component=main;deb.architecture=${arch}" --deb "stable/main/${arch}"
else
echo "Skipping upload of $file as it does not match *.deb"
fi
done
jfrog rt build-collect-env "${{ env.JFROG_CLI_BUILD_NAME }}-deb" "${{ needs.build.outputs.version }}"
jfrog rt build-add-git "${{ env.JFROG_CLI_BUILD_NAME }}-deb" "${{ needs.build.outputs.version }}"
jfrog rt build-publish "${{ env.JFROG_CLI_BUILD_NAME }}-deb" "${{ needs.build.outputs.version }}" --project="${{env.JFROG_CLI_BUILD_PROJECT}}"
- name: "Upload rpm builds to JFrog"
run: |
for file in *; do
if [[ "$file" == *.rpm ]]; then
arch=$(rpm -q --qf "%{ARCH}" -p "$file")
jf rt upload "$file" "${{env.JFROG_CLI_BUILD_PROJECT}}-rpm-dev-local/${{ env.ARTIFACT_NAME }}/${{ needs.build.outputs.version }}/" \
--build-name="${{ env.JFROG_CLI_BUILD_NAME }}-rpm" --build-number="${{ needs.build.outputs.version }}" --project="${{env.JFROG_CLI_BUILD_PROJECT}}" \
--target-props "rpm.distribution=stable;rpm.component=main;rpm.architecture=$arch"
else
echo "Skipping upload of $file as it does not match *.rpm"
fi
done
jfrog rt build-collect-env "${{ env.JFROG_CLI_BUILD_NAME }}-rpm" "${{ needs.build.outputs.version }}"
jfrog rt build-add-git "${{ env.JFROG_CLI_BUILD_NAME }}-rpm" "${{ needs.build.outputs.version }}"
jfrog rt build-publish "${{ env.JFROG_CLI_BUILD_NAME }}-rpm" "${{ needs.build.outputs.version }}" --project="${{env.JFROG_CLI_BUILD_PROJECT}}"
# Our repositories currently don't support generic which would be needed for pkg and zip
publish-release-bundle:
needs:
- sign
- build
- build-docker
- publish-asvec-build
runs-on: ubuntu-latest
steps:
- name: 'Git checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: setup jfrog
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: https://aerospike.jfrog.io
JF_ACCESS_TOKEN: ${{ secrets.JFROG_ACCESS_TOKEN }}
JF_PROJECT: ${{ env.JFROG_CLI_BUILD_PROJECT }}
- name: Create Release Bundle
run: |
echo '{
"name": "${{ env.JFROG_CLI_BUILD_NAME }}",
"version": "${{ needs.build.outputs.version }}",
"description": "Release bundle for ${{github.repository}} version ${{ needs.build.outputs.version }}",
"files": [
{
"project": "${{env.JFROG_CLI_BUILD_PROJECT}}",
"build": "${{ env.JFROG_CLI_BUILD_NAME }}-container"
},
{
"project": "${{env.JFROG_CLI_BUILD_PROJECT}}",
"build": "${{ env.JFROG_CLI_BUILD_NAME }}-deb"
},
{
"project": "${{env.JFROG_CLI_BUILD_PROJECT}}",
"build": "${{ env.JFROG_CLI_BUILD_NAME }}-rpm"
}
]
}' > release-bundle-spec.json
cat release-bundle-spec.json
jf release-bundle-create \
"${{ env.JFROG_CLI_BUILD_NAME }}" "${{ needs.build.outputs.version }}"\
--project ecosystem \
--spec release-bundle-spec.json \
--signing-key aerospike --sync