Skip to content

Instantly share code, notes, and snippets.

@sumanmaity112
Last active September 20, 2023 17:21
Show Gist options
  • Save sumanmaity112/0d917db7fd531faf60e0ac32672f522e to your computer and use it in GitHub Desktop.
Save sumanmaity112/0d917db7fd531faf60e0ac32672f522e to your computer and use it in GitHub Desktop.
A simple GitHub workflow is used to show how to build and publish Java modules in a monorepo.
name: build
on:
push:
branches:
- main
jobs:
build-matrix-config:
runs-on: ubuntu-22.04
outputs:
matrix: ${{ steps.matrix-json.outputs.matrix }}
steps:
- name: Checkout local repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%s")"
shell: bash
- name: Cache last commit sha
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.last_commit_sha
key: ${{ runner.os }}-last_commit_sha-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-last_commit_sha-
- name: create matrix as json
id: matrix-json
run: echo "::set-output name=matrix::$( ./run.sh build-matrix-config | jq -c )"
- name: update last commit sha
run: ./run.sh update-last-commit-sha
build:
name: Run build for ${{ matrix.name }}
runs-on: ubuntu-22.04
needs: [build-matrix-config]
strategy:
matrix: ${{fromJson(needs.build-matrix-config.outputs.matrix)}}
fail-fast: false
steps:
- name: Checkout local repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install jenv
run: |
git clone https://github.com/gcuisinier/jenv.git ~/.jenv
echo "$HOME/.jenv/bin" >> $GITHUB_PATH
- name: Configure jenv
run: |
jenv init -
jenv add $JAVA_HOME_17_X64
- name: Cache gradle wrapper and jars
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
- name: Run tests
run: ./run.sh test ${{ matrix.name }}
- name: Setup ssh agent
id: setup-ssh-agent
if: "contains(github.event.head_commit.message, '[bump-')"
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Create a new release Tag
id: create-release-tag
if: ${{ steps.setup-ssh-agent.conclusion == 'success' }}
run: ./run.sh tag ${{ matrix.name }} Tagged as part of pipeline process
- name: Publish jar
if: ${{ steps.create-release-tag.conclusion == 'success' }}
id: publish-jar
run: ./run.sh publish ${{ matrix.name }}
env:
PACKAGES_USER: ${{ secrets.PACKAGES_USER }}
PACKAGES_SECRET: ${{ secrets.ACCESS_TOKEN }}
- name: Push newly created release tag
if: ${{ steps.publish-jar.conclusion == 'success' }}
run: git push --tags
- name: Upload Spotbug and test report to artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}-build-reports
path: ${{ github.workspace }}/${{ matrix.name }}/build/reports/
#!/usr/bin/env bash
set -euo pipefail
export SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)"
LAST_COMMIT_SHA_FILE_NAME=".last_commit_sha"
function _test() {
local module_dir="${1}"
pushd "${module_dir}" > /dev/null
"${SCRIPT_DIR}/gradlew" clean check
popd > /dev/null
}
function _publish() {
local module_dir="${1}"
pushd "${module_dir}" > /dev/null
"${SCRIPT_DIR}/gradlew" publish
popd > /dev/null
}
function _find_changed_files() {
if test -f "$LAST_COMMIT_SHA_FILE_NAME"; then
local last_commit_sha
last_commit_sha=$(head -n 1 $LAST_COMMIT_SHA_FILE_NAME)
git diff "${GITHUB_SHA}" "${last_commit_sha}" --name-only
else
git show --pretty="" --name-only "${GITHUB_SHA}"
fi
}
function _build_matrix_config() {
# The assumption here is, there is no dependency between the modules, ex- moduleA doesn't depend on moduleB
# This process can be improved/modified depends on the use case
local module_names=(moduleA moduleB)
local changed_modules=()
local changed_files
changed_files=$(_find_changed_files)
for module_name in "${module_names[@]}"; do
if grep -q "^${module_name}/" <<<"${changed_files}"; then
changed_modules+=("${module_name}")
fi
done
if [ ${#changed_modules[@]} -eq 0 ]; then
printf '%s\n' "${module_names[@]}" | jq -R '{"name":.}' | jq -s '{"include": .}'
else
printf '%s\n' "${changed_modules[@]}" | jq -R '{"name":.}' | jq -s '{"include": .}'
fi
}
function _update_last_commit_sha() {
echo "${GITHUB_SHA}" > $LAST_COMMIT_SHA_FILE_NAME
}
function _tag() {
local module_dir="${1}"
shift || true
local message="$*"
pushd "${module_dir}" > /dev/null
"${SCRIPT_DIR}/gradlew" tag -Prelease -Dmessage="${message}"
git describe --tags
popd > /dev/null
}
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)"
. "${SCRIPT_DIR}/lib.sh"
function _usage() {
cat <<EOF
Usage: $0 command
commands:
test [module name] Build and test given/all module(s)
publish [module name] Publishes all publications produced by given module
build-matrix-config Build github action matrix json depends on changed files
update-last-commit-sha Update commit sha in file
tag [module name] [message] Create a release version. Also create a annotated Git tag with given message
EOF
exit 1
}
CMD=${1:-}
shift || true
case ${CMD} in
test) _test "${1:-.}" ;;
publish) _publish "${1}" ;;
build-matrix-config) _build_matrix_config ;;
update-last-commit-sha) _update_last_commit_sha ;;
tag) _tag "$@" ;;
*) _usage ;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment