From 92baa8db17a672f2966106a02fecce204feb577f Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Tue, 15 Mar 2022 16:04:42 +0000 Subject: [PATCH] GitHub release action (#2) * add check-version and workflow * change dockerfile port * only release on push to main --- .github/workflows/react-lint-testing.yml | 4 +- .github/workflows/release.yml | 142 +++++++++++++++++++++++ Dockerfile | 4 +- scripts/check-version.sh | 58 +++++++++ 4 files changed, 203 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100755 scripts/check-version.sh diff --git a/.github/workflows/react-lint-testing.yml b/.github/workflows/react-lint-testing.yml index ba9335f..06604bc 100644 --- a/.github/workflows/react-lint-testing.yml +++ b/.github/workflows/react-lint-testing.yml @@ -2,9 +2,7 @@ name: TestLinting on: push: - branches: '**' - pull_request: - branches: '**' + branches-ignore: ["main"] workflow_dispatch: inputs: tags: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..96debcd --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,142 @@ +name: Release + +on: + push: + branches: ['main'] + +jobs: + preconditions: + runs-on: ubuntu-latest + outputs: + repo_name: ${{ steps.repo_ids.outputs.REPO_NAME }} + org_name: ${{ steps.repo_ids.outputs.ORG_NAME }} + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Check token + run: | + if [ -z "${{ secrets.GITHUB_TOKEN }}"]; then + echo "Must provide a GITHUB_TOKEN secret in order to run release workflow" + exit 1 + fi + - name: Get repository identifiers + id: repo_ids + run: | + REPO_NAME=$(echo "${{ github.event.repository.name }}" | tr '[:upper:]' '[:lower:]') + ORG_NAME=$(echo "${{ github.event.repository.owner.name }}" | tr '[:upper:]' '[:lower:]') + echo "::set-output name=REPO_NAME::$REPO_NAME" + echo "::set-output name=ORG_NAME::$ORG_NAME" + + lint: + name: Run lint + runs-on: ubuntu-latest + needs: [preconditions] + steps: + - uses: actions/checkout@master + - uses: actions/setup-node@master + with: + node-version: 16.x + - name: Use npm v8 + run: npm install -g npm@8 + - name: Cache Node.js modules + uses: actions/cache@v1 + with: + path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-node- + ${{ runner.OS }}- + - name: Install Packages + run: npm ci + - name: Lint + run: npm run lint + + check-version: + name: 'Check version' + runs-on: ubuntu-latest + outputs: + is_new_version: ${{ steps.get_version.outputs.IS_NEW_VERSION }} + version: ${{ steps.get_version.outputs.VERSION }} + build_date: ${{ steps.get_version.outputs.BUILD_DATE }} + is_prerelease: ${{ steps.get_version.outputs.IS_PRERELEASE }} + + steps: + - uses: actions/checkout@v2 + - run: git fetch --depth=1 --tags origin + - name: Install yq + run: sudo snap install yq + - name: Check Build Version + id: get_version + run: ./scripts/check-version.sh + shell: bash + - name: Skipping release as version has not increased + if: steps.get_version.outputs.IS_NEW_VERSION != 'true' + shell: bash + run: | + echo "Skipping release as current version has already been published" + + publish: + name: 'Publish package' + needs: + - preconditions + - lint + - check-version + runs-on: ubuntu-latest + if: ${{ needs.check-version.outputs.is_new_version == 'true' }} + + steps: + - uses: actions/checkout@v2 + + # Docker build + - name: Setup QEMU + uses: docker/setup-qemu-action@v1 + with: + platforms: all + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + buildkitd-flags: '--debug' + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: $GITHUB_ACTOR + password: ${{ secrets.GITHUB_TOKEN }} + - name: Publish multi-arch image + uses: docker/build-push-action@v2 + with: + push: true + builder: ${{ steps.buildx.outputs.name }} + context: . + file: ./Dockerfile + platforms: linux/amd64 + tags: | + ghcr.io/${{ needs.preconditions.outputs.org_name }}/${{ needs.preconditions.outputs.repo_name }}:${{ needs.check-version.outputs.version }} + ghcr.io/${{ needs.preconditions.outputs.org_name }}/${{ needs.preconditions.outputs.repo_name }}:latest + labels: | + org.opencontainers.image.title=${{ needs.preconditions.outputs.repo_name }} + org.opencontainers.image.description=${{ github.event.repository.description }} + org.opencontainers.image.source=${{ github.event.repository.html_url }} + org.opencontainers.image.url=${{ github.event.repository.html_url }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=${{ needs.check-version.outputs.version }} + org.opencontainers.image.created=${{ needs.check-version.outputs.build_date }} + + # Build github release + - name: Build release version + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: ${{ needs.check-version.outputs.version }} + prerelease: false + title: Release ${{ needs.check-version.outputs.version }} + - name: Build release latest + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: latest + prerelease: false + title: Latest Release ${{ needs.check-version.outputs.version }} diff --git a/Dockerfile b/Dockerfile index cc5558f..6a464be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,11 +19,11 @@ FROM node:$NODE_VERSION AS runtime RUN npm -g install npm@8.x.x WORKDIR /veritable-authority -ENV PORT 3004 +ENV PORT 3000 COPY --from=build /veritable-authority/build . RUN npm install -g serve -EXPOSE 3004 +EXPOSE 3000 CMD ["serve", "/veritable-authority"] \ No newline at end of file diff --git a/scripts/check-version.sh b/scripts/check-version.sh new file mode 100755 index 0000000..870b611 --- /dev/null +++ b/scripts/check-version.sh @@ -0,0 +1,58 @@ +#! /bin/bash + +# exit when any command fails +set -e + +function check_versions_consistent () { + local PACKAGE_VERSION=$(yq eval '.version' ./package.json) + local PACKAGE_LOCK_VERSION=$(yq eval '.version' ./package-lock.json) + + if [ "$PACKAGE_VERSION" != "$PACKAGE_LOCK_VERSION" ]; then + echo "Inconsistent versions detected" + echo "PACKAGE_VERSION: $PACKAGE_VERSION" + echo "PACKAGE_LOCK_VERSION: $PACKAGE_LOCK_VERSION" + exit 1 + fi +} + +check_versions_consistent + +function check_version_greater () { + local current=$1 + local git_versions="${2:-0.0.0}" + + # check if current exists in git_versions, if so not a new version + if [ -n "$(printf "$git_versions" | grep -Fx $current)" ]; then + return 1 + fi + + # sort all - note crazy hack to deal with prerelease versions by appending a _ character to release versions + local sorted_versions=($(printf "$git_versions\n$current" | awk '{ if ($1 ~ /-/) print; else print $0"_" ; }' | sort -rV | sed 's/_$//')) + + # check if the top sorted version equals the current verison. If so we have a new version + if [ "${sorted_versions[0]}" == "$current" ]; then + return 0 + else + return 1 + fi +} + +# Get published git tags that match semver regex with a "v" prefix then remove the "v" character +PUBLISHED_VERSIONS=$(git tag | grep "^v[0-9]\+\.[0-9]\+\.[0-9]\+\(\-[a-zA-Z-]\+\(\.[0-9]\+\)*\)\{0,1\}$" | sed 's/^v\(.*\)$/\1/') +# Get the current version from node Cargo.toml +CURRENT_VERSION=$(yq eval '.version' ./package.json) + +if check_version_greater "$CURRENT_VERSION" "$PUBLISHED_VERSIONS"; then + echo "##[set-output name=VERSION;]v$CURRENT_VERSION" + echo "##[set-output name=BUILD_DATE;]$(date -u +'%Y-%m-%dT%H:%M:%SZ')" + echo "##[set-output name=IS_NEW_VERSION;]true" + if [[ $CURRENT_VERSION =~ [-] ]]; then + echo "##[set-output name=IS_PRERELEASE;]true" + echo "##[set-output name=NPM_RELEASE_TAG;]next" + else + echo "##[set-output name=IS_PRERELEASE;]false" + echo "##[set-output name=NPM_RELEASE_TAG;]latest" + fi +else + echo "##[set-output name=IS_NEW_VERSION;]false" +fi