From 04bdc76e6b29bef9701bfdd3ee03afe8d23cff13 Mon Sep 17 00:00:00 2001
From: Philipp Schlarb
Date: Thu, 7 Apr 2022 11:36:16 +0000
Subject: [PATCH 01/10] Switched to sharedGHA
Signed-off-by: Philipp Schlarb
---
.github/workflows/publishRelease.yaml | 120 +++++++++++
.github/workflows/push_pr.yaml | 119 ++---------
.github/workflows/releasepr.yaml | 71 +++++++
.../{test.yaml => reuseable_test.yaml} | 0
.github/workflows/tag.yaml | 64 ++++++
build-scripts/ubuntu-1604/Dockerfile | 30 ---
build-scripts/ubuntu-1604/README.md | 30 ---
.../ubuntu-1604/build-3rd-parties-docker.sh | 24 ---
.../ubuntu-1604/build-3rd-parties.sh | 51 -----
.../ubuntu-1604/build-indy-node-docker.sh | 31 ---
build-scripts/ubuntu-1604/build-indy-node.sh | 42 ----
build-scripts/ubuntu-1604/postinst | 8 -
build-scripts/ubuntu-1604/postinst_node | 198 ------------------
build-scripts/ubuntu-1604/preinst_node | 5 -
build-scripts/ubuntu-1604/prepare-package.sh | 58 -----
build-scripts/ubuntu-1604/prerm | 7 -
...{build-indy-node.sh => build-indy_node.sh} | 0
17 files changed, 276 insertions(+), 582 deletions(-)
create mode 100644 .github/workflows/publishRelease.yaml
create mode 100644 .github/workflows/releasepr.yaml
rename .github/workflows/{test.yaml => reuseable_test.yaml} (100%)
create mode 100644 .github/workflows/tag.yaml
delete mode 100644 build-scripts/ubuntu-1604/Dockerfile
delete mode 100644 build-scripts/ubuntu-1604/README.md
delete mode 100755 build-scripts/ubuntu-1604/build-3rd-parties-docker.sh
delete mode 100755 build-scripts/ubuntu-1604/build-3rd-parties.sh
delete mode 100755 build-scripts/ubuntu-1604/build-indy-node-docker.sh
delete mode 100755 build-scripts/ubuntu-1604/build-indy-node.sh
delete mode 100755 build-scripts/ubuntu-1604/postinst
delete mode 100755 build-scripts/ubuntu-1604/postinst_node
delete mode 100755 build-scripts/ubuntu-1604/preinst_node
delete mode 100755 build-scripts/ubuntu-1604/prepare-package.sh
delete mode 100755 build-scripts/ubuntu-1604/prerm
rename build-scripts/ubuntu-2004/{build-indy-node.sh => build-indy_node.sh} (100%)
diff --git a/.github/workflows/publishRelease.yaml b/.github/workflows/publishRelease.yaml
new file mode 100644
index 000000000..7753c0aa3
--- /dev/null
+++ b/.github/workflows/publishRelease.yaml
@@ -0,0 +1,120 @@
+name: Triggered by Version Bump merged
+
+#disable all tags and enable all brannches and only version file
+on:
+ push:
+ branches-ignore:
+ - update-rc-version
+ - update-version
+ paths:
+ - '!**'
+ - "indy_node/__version__.json"
+
+jobs:
+ release-infos:
+ name: release-infos
+ runs-on: ubuntu-latest
+ outputs:
+ isVersionBump: ${{ steps.get-release-info.outputs.isVersionBump }}
+ isPreRelease: ${{ steps.get-release-info.outputs.isRC }}
+ versionTag: ${{ steps.get-release-info.outputs.versionTag }}
+ component: ${{ steps.get-release-info.outputs.component}}
+ CACHE_KEY_BUILD: ${{ steps.workflow-setup.outputs.CACHE_KEY_BUILD }}
+ UBUNTU_VERSION: ${{ steps.workflow-setup.outputs.UBUNTU_VERSION }}
+ # Expose the lowercase version of the GitHub repository name
+ # to all subsequent jobs that reference image repositories
+ # as the push and pull operations require the URL of the repository
+ # to be in lowercase.
+ GITHUB_REPOSITORY_NAME: ${{ steps.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
+ distribution: ${{ steps.workflow-setup.outputs.distribution }}
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v2
+ - name: get-release-info
+ id: get-release-info
+ uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ with:
+ versionString: "${{ github.event.head_commit.message }}"
+ - name: workflow-setup
+ id: workflow-setup
+ uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
+
+ createRelease:
+ name: Create Release
+ needs: [release-infos]
+ if: needs.release-infos.outputs.isVersionBump == 'true'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Download Node Artifacts from Github Action Artifacts
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: releasepr.yaml
+ workflow_conclusion: success
+ name: indy_node-deb
+ path: artifacts/indy_node-deb
+ - name: Download Node Artifacts from Github Action Artifacts
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: releasepr.yaml
+ workflow_conclusion: success
+ name: indy_node-python
+ path: artifacts/indy_node-python
+ - name: Download Node Artifacts from Github Action Artifacts
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: releasepr.yaml
+ workflow_conclusion: success
+ name: third-party-dependencies
+ path: artifacts/third-party-dependencies
+ - uses: actions/upload-artifact@v2
+ with:
+ name: third-party-dependencies
+ path: artifacts/third-party-dependencies
+ retention-days: 5
+ - uses: actions/upload-artifact@v2
+ with:
+ name: indy_node-deb
+ path: artifacts/indy_node-deb
+ retention-days: 5
+ - uses: actions/upload-artifact@v2
+ with:
+ name: indy_node-python
+ path: artifacts/indy_node-python
+ retention-days: 5
+ - name: Zip Files for Release
+ run: |
+ zip -r artifacts/indy_node-deb.zip artifacts/indy_node-deb
+ zip -r artifacts/indy_node-python.zip artifacts/indy_node-python
+ zip -r artifacts/third-party-dependencies.zip artifacts/third-party-dependencies
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: ${{ needs.release-infos.outputs.VERSIONTAG }}
+ files: |
+ artifacts/**.zip
+ generate_release_notes: true
+ body: "[${{ needs.release-infos.outputs.VERSIONTAG }}] "
+ prerelease: ${{ needs.release-infos.outputs.isPreRelease }}
+ target_commitish: ${{github.event.ref}}
+ name: "${{ needs.release-infos.outputs.VERSIONTAG }}"
+ token: ${{ secrets.BOT_PR_PAT }}
+
+ publish_artifacts:
+ name: Publish Artifacts
+ needs: [release-infos, createRelease]
+ if: needs.release-infos.outputs.isVersionBump == 'true'
+ uses: pschlarb/indy-shared-gha/.github/workflows/publish_artifacts.yaml@parametrization
+ with:
+ COMPONENT: ${{ needs.release-infos.component }}
+ UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+ distribution: ${{ needs.release-infos.outputs.distribution }}
+ moduleName: indy_node
+ secrets:
+ INDY_ARTIFACTORY_REPO_CONFIG: ${{ secrets.INDY_ARTIFACTORY_REPO_CONFIG }}
+ PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.github/workflows/push_pr.yaml b/.github/workflows/push_pr.yaml
index 6cd230ab2..d152758e3 100644
--- a/.github/workflows/push_pr.yaml
+++ b/.github/workflows/push_pr.yaml
@@ -16,118 +16,39 @@ jobs:
name: Initialize Workflow
runs-on: ubuntu-latest
outputs:
- CACHE_KEY_BUILD: ${{ steps.cache.outputs.CACHE_KEY_BUILD }}
- UBUNTU_VERSION: ${{ steps.cache.outputs.UBUNTU_VERSION }}
+ CACHE_KEY_BUILD: ${{ steps.setup.outputs.CACHE_KEY_BUILD }}
+ UBUNTU_VERSION: ${{ steps.setup.outputs.UBUNTU_VERSION }}
# Expose the lowercase version of the GitHub repository name
# to all subsequent jobs that reference image repositories
# as the push and pull operations require the URL of the repository
# to be in lowercase.
- GITHUB_REPOSITORY_NAME: ${{ steps.repository-name.outputs.lowercase }}
- GITHUB_REF: ${{ steps.cache.outputs.GITHUB_REF }}
- distribution: ${{ steps.cache.outputs.distribution }}
- isDev: ${{ steps.build-flags.outputs.isDev }}
- isRC: ${{ steps.build-flags.outputs.isRC }}
- publish: ${{ steps.build-flags.outputs.publish }}
+ GITHUB_REPOSITORY_NAME: ${{ steps.setup.outputs.GITHUB_REPOSITORY_NAME }}
+ distribution: ${{ steps.setup.outputs.distribution }}
+ publish: ${{ steps.setup.outputs.publish }}
steps:
- - name: Git checkout
+ - name: checkout source code
uses: actions/checkout@v2
-
- - name: Convert the GitHub repository name to lowercase
- id: repository-name
- uses: ASzc/change-string-case-action@v1
- with:
- string: ${{ github.repository }}
-
- - name: Set outputs
- id: cache
- run: |
- # Set variables according to version of ubuntu
- if [[ "${{github.base_ref}}" == "master" || "${{github.ref}}" == "refs/heads/master" ]]; then
- echo "::set-output name=CACHE_KEY_BUILD::${{ hashFiles('.github/workflows/build/Dockerfile.ubuntu-1604') }}"
- echo "::set-output name=UBUNTU_VERSION::ubuntu-1604"
- echo "::set-output name=distribution::xenial"
- fi
- if [[ "${{github.base_ref}}" == "ubuntu-20.04-upgrade" || "${{github.ref}}" == "refs/heads/ubuntu-20.04-upgrade" ]]; then
- echo "::set-output name=CACHE_KEY_BUILD::${{ hashFiles('.github/workflows/build/Dockerfile.ubuntu-2004') }}"
- echo "::set-output name=UBUNTU_VERSION::ubuntu-2004"
- echo "::set-output name=distribution::focal"
- fi
- if [[ "${{github.base_ref}}" == "feature/did-indy-new" || "${{github.ref}}" == "refs/heads/feature/did-indy-new" ]]; then
- echo "::set-output name=CACHE_KEY_BUILD::${{ hashFiles('.github/workflows/build/Dockerfile.ubuntu-2004') }}-0"
- echo "::set-output name=UBUNTU_VERSION::ubuntu-2004"
- echo "::set-output name=distribution::focal"
- fi
-
-
- if [[ "${{github.base_ref}}" == 'master' || "${{github.ref}}" == 'refs/heads/master' || "${{github.base_ref}}" == 'main' || "${{github.ref}}" == 'refs/heads/main' ]]; then
- echo "::set-output name=GITHUB_REF::main"
- elif [[ "${{github.base_ref}}" == 'release*' || "${{github.ref}}" == 'refs/heads/release*' ]]; then
- echo "::set-output name=GITHUB_REF::rc"
- elif [[ "${{github.base_ref}}" == 'stable' || "${{github.ref}}" == 'refs/heads/stable' ]]; then
- echo "::set-output name=GITHUB_REF::stable"
- else
- echo "::set-output name=GITHUB_REF::dev"
- fi
-
- - name: Set build flags
- id: build-flags
- run: |
-
- if [[ "${{steps.cache.outputs.GITHUB_REF}}" == 'dev' || "${{steps.cache.outputs.GITHUB_REF}}" == 'main' ]]; then
- echo "::set-output name=isDev::true"
- else
- echo "::set-output name=isDev::false"
- fi
-
- if [[ "${{steps.cache.outputs.GITHUB_REF}}" == 'rc' ]]; then
- echo "::set-output name=isRC::true"
- else
- echo "::set-output name=isRC::false"
- fi
-
- # Ensure publishing is only performed when the build is executed from the main (hyperledger/indy-node) repository.
- if [[ ${{github.event.repository.full_name}} == 'hyperledger/indy-node' && ${{github.event_name}} == 'push' && ( ${{steps.cache.outputs.GITHUB_REF}} == 'main' || ${{steps.cache.outputs.GITHUB_REF}} == 'rc' || ${{steps.cache.outputs.GITHUB_REF}} == 'stable' || ${{steps.cache.outputs.GITHUB_REF}} == 'dev' ) ]]; then
- echo "::set-output name=publish::true"
- else
- echo "::set-output name=publish::false"
- fi
+ - name: setup
+ id: setup
+ uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
lint:
name: Lint
- # Reference to workflow-setup job is required to access the GITHUB_REPOSITORY_NAME output.
- needs: [workflow-setup]
- runs-on: ubuntu-20.04
- steps:
- - name: Check out code
- uses: actions/checkout@v2
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: '3.8'
- - uses: actions/cache@v2
- with:
- path: ~/.cache/pip
- key: ${{ runner.os }}-pip-lint
- restore-keys: |
- ${{ runner.os }}-pip-lint
- - name: Install flake8
- run: pip install flake8==3.8.4 pep8==1.7.1 pep8-naming==0.6.1
- - name: Lint with flake8
- run: python3 -m flake8 .
+ uses: pschlarb/indy-shared-gha/.github/workflows/lint.yaml@parametrization
build-image:
name: Create Builder Image
needs: [workflow-setup, lint]
- uses: ./.github/workflows/buildimage.yaml
+ uses: pschlarb/indy-shared-gha/.github/workflows/buildimage.yaml@parametrization
with:
CACHE_KEY_BUILD: ${{ needs.workflow-setup.outputs.CACHE_KEY_BUILD }}
- GITHUB_REPOSITORY_NAME: ${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
+ DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
indy_node_tests:
name: Indy Node Tests
needs: [workflow-setup, build-image]
- uses: ./.github/workflows/test.yaml
+ uses: ./.github/workflows/reuseable_test.yaml
with:
GITHUB_REPOSITORY_NAME: ${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
@@ -135,22 +56,24 @@ jobs:
build_packages:
name: Build Packages
needs: [workflow-setup, indy_node_tests]
- uses: ./.github/workflows/buildpackages.yaml
+ uses: pschlarb/indy-shared-gha/.github/workflows/buildpackages.yaml@parametrization
with:
- GITHUB_REPOSITORY_NAME: ${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
+ DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ needs.release-infos.outputs.UBUNTU_VERSION }}
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
- isDev: ${{ needs.workflow-setup.outputs.isDev }}
- isRC: ${{ needs.workflow-setup.outputs.isRC }}
+ isDev: true
+ isRC: false
+ moduleName: indy_node
publish_artifacts:
name: Publish Artifacts
needs: [workflow-setup, build_packages]
if: needs.workflow-setup.outputs.publish == 'true'
- uses: ./.github/workflows/publish_artifacts.yaml
+ uses: pschlarb/indy-shared-gha/.github/workflows/publish_artifacts.yaml@parametrization
with:
- GITHUB_REF: ${{ needs.workflow-setup.outputs.GITHUB_REF }}
+ COMPONENT: 'dev'
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
distribution: ${{ needs.workflow-setup.outputs.distribution }}
+ moduleName: indy_node
secrets:
INDY_ARTIFACTORY_REPO_CONFIG: ${{ secrets.INDY_ARTIFACTORY_REPO_CONFIG }}
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.github/workflows/releasepr.yaml b/.github/workflows/releasepr.yaml
new file mode 100644
index 000000000..26b4adffa
--- /dev/null
+++ b/.github/workflows/releasepr.yaml
@@ -0,0 +1,71 @@
+name: Triggered by Version Bump Release PR
+
+on:
+ pull_request:
+ paths:
+ - '!**'
+ - "indy_node/__version__.json"
+
+jobs:
+ release-infos:
+ name: infos
+ runs-on: ubuntu-latest
+ outputs:
+ isVersionBump: ${{ steps.get-release-info.outputs.isVersionBump }}
+ isPreRelease: ${{ steps.get-release-info.outputs.isRC }}
+ CACHE_KEY_BUILD: ${{ steps.workflow-setup.outputs.CACHE_KEY_BUILD }}
+ UBUNTU_VERSION: ${{ steps.workflow-setup.outputs.UBUNTU_VERSION }}
+ # Expose the lowercase version of the GitHub repository name
+ # to all subsequent jobs that reference image repositories
+ # as the push and pull operations require the URL of the repository
+ # to be in lowercase.
+ GITHUB_REPOSITORY_NAME: ${{ steps.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
+ distribution: ${{ steps.workflow-setup.outputs.distribution }}
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v2
+ - name: get-release-info
+ id: get-release-info
+ uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ with:
+ versionString: "${{ github.event.pull_request.body }}"
+ - name: workflow-setup
+ id: workflow-setup
+ uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
+
+ lint:
+ name: Lint
+ needs: [release-infos]
+ if: needs.release-infos.outputs.isVersionBump == 'true'
+ uses: pschlarb/indy-shared-gha/.github/workflows/lint.yaml@parametrization
+
+ build-image:
+ name: Create Builder Image
+ needs: [release-infos, lint]
+ uses: pschlarb/indy-shared-gha/.github/workflows/buildimage.yaml@parametrization
+ with:
+ CACHE_KEY_BUILD: ${{ needs.release-infos.outputs.CACHE_KEY_BUILD }}
+ DOCKER_IMAGE: ghcr.io/${{ needs.release-infos.outputs.GITHUB_REPOSITORY_NAME }}/node-build
+ UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+
+
+ indy_node_tests:
+ name: Indy Node Tests
+ needs: [release-infos, build-image]
+ uses: ./.github/workflows/reuseable_test.yaml
+ with:
+ GITHUB_REPOSITORY_NAME: ${{ needs.release-infos.outputs.GITHUB_REPOSITORY_NAME }}
+ UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+
+
+ build_packages:
+ name: Build Packages
+ needs: [release-infos, indy_node_tests]
+ if: needs.release-infos.outputs.isVersionBump == 'true'
+ uses: pschlarb/indy-shared-gha/.github/workflows/buildpackages.yaml@parametrization
+ with:
+ DOCKER_IMAGE: ghcr.io/${{ needs.release-infos.outputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+ UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+ isDev: 'false'
+ isRC: '${{ needs.release-infos.outputs.isPreRelease }}'
+ moduleName: indy_node
diff --git a/.github/workflows/test.yaml b/.github/workflows/reuseable_test.yaml
similarity index 100%
rename from .github/workflows/test.yaml
rename to .github/workflows/reuseable_test.yaml
diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml
new file mode 100644
index 000000000..201d83d7a
--- /dev/null
+++ b/.github/workflows/tag.yaml
@@ -0,0 +1,64 @@
+name: Triggered by set Tag
+
+on:
+ push:
+ tags:
+ - setRelease-v**
+
+jobs:
+ taginfos:
+ name: get Tag infos
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.get-release-info.outputs.version }}
+ versionTag: ${{ steps.get-release-info.outputs.versionTag }}
+ prBranch: ${{ steps.get-release-info.outputs.prBranch }}
+ BASE: ${{ steps.branch.outputs.BASE}}
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v1
+ - name: extract branch
+ id: branch
+ run: |
+ raw=$(git branch -r --contains ${{ github.ref }})
+ branch=${raw/origin\/}
+ echo ::set-output\ name=BASE::$branch
+ echo "::debug::BASE is being set to $branch"
+ - name: get-release-info
+ id: get-release-info
+ uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ with:
+ versionString: "${{ github.ref }}"
+
+
+ bump_version:
+ name: Bump Version Number
+ needs: taginfos
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v2
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
+ - name: Install deps for version change
+ run: pip install base58
+ - name: Prepare package and set version
+ run: |
+ ./bump_version.sh ${{ needs.taginfos.outputs.VERSION }}
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v3
+ with:
+ author: ${{ github.actor }} <${{ github.event.pusher.email }}>
+ committer: ${{ github.actor }} <${{ github.event.pusher.email }}>
+ signoff: true
+ commit-message: Update Version number for v${{ needs.taginfos.outputs.version }}
+ base: ${{ needs.taginfos.outputs.BASE }}
+ branch: ${{ needs.taginfos.outputs.prBranch }}
+ title: "[${{ needs.taginfos.outputs.versionTag }}] - Update Version Number for Release"
+ body: "[${{ needs.taginfos.outputs.versionTag }}] - Update Version number for Release"
+ delete-branch: true
+ token: ${{ secrets.BOT_PR_PAT }}
+
\ No newline at end of file
diff --git a/build-scripts/ubuntu-1604/Dockerfile b/build-scripts/ubuntu-1604/Dockerfile
deleted file mode 100644
index 1c9f348eb..000000000
--- a/build-scripts/ubuntu-1604/Dockerfile
+++ /dev/null
@@ -1,30 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update -y && apt-get install -y \
- # common stuff
- git \
- wget \
- unzip \
- python3.5 \
- python3-pip \
- python3-venv \
- # fmp
- ruby \
- ruby-dev \
- rubygems \
- gcc \
- make \
- && rm -rf /var/lib/apt/lists/*
-
-# issues with pip>=10:
-# https://github.com/pypa/pip/issues/5240
-# https://github.com/pypa/pip/issues/5221
-RUN python3 -m pip install -U pip setuptools \
- && pip3 list
-
-# install fpm
-RUN gem install --no-ri --no-rdoc rake fpm
-
-WORKDIR /root
-
-ADD . /root
diff --git a/build-scripts/ubuntu-1604/README.md b/build-scripts/ubuntu-1604/README.md
deleted file mode 100644
index d972042dc..000000000
--- a/build-scripts/ubuntu-1604/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-### Build indy-node using docker
-
-```
-./build-indy-node-docker.sh
-```
-Built package is placed in a docker volume `indy-node-deb-u1604`.
-
-### Build indy-node
-
-```
-./build-indy-node.sh
-```
-
-Built package is placed in the `output-path` folder.
-
-### Build 3rd-party dependencies using docker
-
-```
-./build-3rd-parties-docker.sh
-```
-
-Built packages are placed in a docker volume `indy-node-deb-u1604`.
-
-### Build 3rd-party dependencies
-
-```
-./build-3rd-parties-docker.sh
-```
-
-Built packages are placed in the `output-path` folder.
diff --git a/build-scripts/ubuntu-1604/build-3rd-parties-docker.sh b/build-scripts/ubuntu-1604/build-3rd-parties-docker.sh
deleted file mode 100755
index e333bd28a..000000000
--- a/build-scripts/ubuntu-1604/build-3rd-parties-docker.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-set -e
-
-if [ -z "$2" ]; then
- CMD="/root/build-3rd-parties.sh /output"
-else
- CMD="$2"
-fi
-
-PKG_NAME=indy-node
-IMAGE_NAME="${PKG_NAME}-build-u1604"
-OUTPUT_VOLUME_NAME="${1:-"${PKG_NAME}-deb-u1604"}"
-
-docker build -t "${PKG_NAME}-build-u1604" -f Dockerfile .
-docker volume create --name "${OUTPUT_VOLUME_NAME}"
-
-docker run \
- -i \
- --rm \
- -v "${OUTPUT_VOLUME_NAME}:/output" \
- "${IMAGE_NAME}" \
- $CMD
diff --git a/build-scripts/ubuntu-1604/build-3rd-parties.sh b/build-scripts/ubuntu-1604/build-3rd-parties.sh
deleted file mode 100755
index 4b7311b73..000000000
--- a/build-scripts/ubuntu-1604/build-3rd-parties.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-set -x
-
-OUTPUT_PATH="${1:-.}"
-
-function build_from_pypi {
- PACKAGE_NAME="$1"
-
- if [ -z "$2" ]; then
- PACKAGE_VERSION=""
- else
- PACKAGE_VERSION="==$2"
- fi
- POSTINST_TMP="postinst-${PACKAGE_NAME}"
- PREREM_TMP="prerm-${PACKAGE_NAME}"
- cp postinst "${POSTINST_TMP}"
- cp prerm "${PREREM_TMP}"
- sed -i "s/{package_name}/python3-${PACKAGE_NAME}/" "${POSTINST_TMP}"
- sed -i "s/{package_name}/python3-${PACKAGE_NAME}/" "${PREREM_TMP}"
-
- fpm --input-type "python" \
- --output-type "deb" \
- --architecture "amd64" \
- --verbose \
- --python-package-name-prefix "python3"\
- --python-bin "/usr/bin/python3" \
- --exclude "*.pyc" \
- --exclude "*.pyo" \
- --maintainer "Hyperledger " \
- --after-install "${POSTINST_TMP}" \
- --before-remove "${PREREM_TMP}" \
- --package "${OUTPUT_PATH}" \
- "${PACKAGE_NAME}${PACKAGE_VERSION}"
-
- rm "${POSTINST_TMP}"
- rm "${PREREM_TMP}"
-}
-
-# build 3rd parties:
-# build_from_pypi
-# TODO duplicates list from Jenkinsfile.cd
-
-SCRIPT_PATH="${BASH_SOURCE[0]}"
-pushd `dirname ${SCRIPT_PATH}` >/dev/null
-
-build_from_pypi timeout-decorator 0.4.0
-build_from_pypi distro 1.3.0
-
-popd >/dev/null
\ No newline at end of file
diff --git a/build-scripts/ubuntu-1604/build-indy-node-docker.sh b/build-scripts/ubuntu-1604/build-indy-node-docker.sh
deleted file mode 100755
index f27b9bff6..000000000
--- a/build-scripts/ubuntu-1604/build-indy-node-docker.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash -xe
-
-PKG_SOURCE_PATH="$1"
-VERSION="$2"
-PKG_NAME=indy-node
-IMAGE_NAME="${PKG_NAME}-build-u1604"
-OUTPUT_VOLUME_NAME="${3:-"${PKG_NAME}-deb-u1604"}"
-PACKAGE_VERSION="${4:-$VERSION}"
-
-if [[ (-z "${PKG_SOURCE_PATH}") || (-z "${VERSION}") ]]; then
- echo "Usage: $0 [ [package-version]]"
- exit 1;
-fi
-
-if [ -z "$5" ]; then
- CMD="/root/build-${PKG_NAME}.sh /input ${VERSION} /output ${PACKAGE_VERSION}"
-else
- CMD="$5"
-fi
-
-docker build -t "${IMAGE_NAME}" -f Dockerfile .
-docker volume create --name "${OUTPUT_VOLUME_NAME}"
-
-docker run \
- -i \
- --rm \
- -v "${PKG_SOURCE_PATH}:/input" \
- -v "${OUTPUT_VOLUME_NAME}:/output" \
- -e PKG_NAME="${PKG_NAME}" \
- "${IMAGE_NAME}" \
- $CMD
diff --git a/build-scripts/ubuntu-1604/build-indy-node.sh b/build-scripts/ubuntu-1604/build-indy-node.sh
deleted file mode 100755
index 5ac86fc2f..000000000
--- a/build-scripts/ubuntu-1604/build-indy-node.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash -xe
-
-INPUT_PATH="$1"
-VERSION="$2"
-OUTPUT_PATH="${3:-.}"
-PACKAGE_VERSION=${4:-$VERSION}
-
-PACKAGE_NAME=indy-node
-
-# copy the sources to a temporary folder
-TMP_DIR="$(mktemp -d)"
-cp -r "${INPUT_PATH}/." "${TMP_DIR}"
-
-# prepare the sources
-cd "${TMP_DIR}/build-scripts/ubuntu-1604"
-./prepare-package.sh "${TMP_DIR}" indy_node "${VERSION}" debian-packages
-
-
-sed -i "s/{package_name}/${PACKAGE_NAME}/" "prerm"
-
-fpm --input-type "python" \
- --output-type "deb" \
- --architecture "amd64" \
- --verbose \
- --python-package-name-prefix "python3" \
- --python-bin "/usr/bin/python3" \
- --exclude "*.pyc" \
- --exclude "*.pyo" \
- --depends at \
- --depends iptables \
- --depends libsodium18 \
- --no-python-fix-dependencies \
- --maintainer "Hyperledger " \
- --before-install "preinst_node" \
- --after-install "postinst_node" \
- --before-remove "prerm" \
- --name "${PACKAGE_NAME}" \
- --version ${PACKAGE_VERSION} \
- --package "${OUTPUT_PATH}" \
- "${TMP_DIR}"
-
-rm -rf "${TMP_DIR}"
diff --git a/build-scripts/ubuntu-1604/postinst b/build-scripts/ubuntu-1604/postinst
deleted file mode 100755
index cf749a657..000000000
--- a/build-scripts/ubuntu-1604/postinst
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# Automatically added from template:
-if which py3compile >/dev/null 2>&1; then
- py3compile -O -p {package_name} /usr/local/lib/python3.5/dist-packages/
-fi
-
-# End automatically added section
diff --git a/build-scripts/ubuntu-1604/postinst_node b/build-scripts/ubuntu-1604/postinst_node
deleted file mode 100755
index a13ddcad6..000000000
--- a/build-scripts/ubuntu-1604/postinst_node
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/bash
-
-# it should be fixed
-ENABLE_STDOUT_LOGGING="enableStdOutLogging"
-GENERAL_CONFIG_DIR="/etc/indy"
-GENERAL_DATA_DIR="/var/lib/indy"
-GENERAL_LOG_DIR="/var/log/indy"
-
-INSTALL_DIR='/usr/local/lib/python3.5/dist-packages'
-
-NOFILES_SOFT_LIMIT=65536
-NOFILES_HARD_LIMIT=131072
-
-CLIENT_CONNECTIONS_LIMIT=500
-
-
-# create general indy config folder if does not exist
-mkdir -p $GENERAL_CONFIG_DIR
-# create general indy data folder if does not exist
-mkdir -p $GENERAL_DATA_DIR
-# create general indy log folder if does not exist
-mkdir -p $GENERAL_LOG_DIR
-
-# create indy node config if does not exist
-if [ ! -f $GENERAL_CONFIG_DIR/indy_config.py ]; then
- cp $INSTALL_DIR/indy_node/general_config/indy_config.py $GENERAL_CONFIG_DIR
-else
- if [ -z "$(grep $ENABLE_STDOUT_LOGGING $GENERAL_CONFIG_DIR/indy_config.py)" ]; then
- printf "\n%s\n%s\n" "# Disable stdout logging" "$ENABLE_STDOUT_LOGGING = False" >> $GENERAL_CONFIG_DIR/indy_config.py
- fi
-fi
-
-chmod -R ug+rwx $GENERAL_CONFIG_DIR
-chmod -R ug+rwx $GENERAL_DATA_DIR
-chmod -R ug+rwx $GENERAL_LOG_DIR
-
-
-# init_indy_node script
-cat < /usr/local/bin/init_indy_node
-#!/bin/bash
-
-if [ \$# -lt 5 ]; then
- echo ""
- echo "Usage: \$0 name ip port client_ip client_port [seed]";
- echo " name - node name";
- echo " ip - node IP";
- echo " port - node port";
- echo " client_ip - node client IP";
- echo " client_port - node client port";
- echo " seed - node seed";
- echo ""
- exit 1;
-fi
-
-echo "NODE_NAME=\$1" > $GENERAL_CONFIG_DIR/indy.env
-echo "NODE_IP=\$2" >> $GENERAL_CONFIG_DIR/indy.env
-echo "NODE_PORT=\$3" >> $GENERAL_CONFIG_DIR/indy.env
-echo "NODE_CLIENT_IP=\$4" >> $GENERAL_CONFIG_DIR/indy.env
-echo "NODE_CLIENT_PORT=\$5" >> $GENERAL_CONFIG_DIR/indy.env
-echo "CLIENT_CONNECTIONS_LIMIT=$CLIENT_CONNECTIONS_LIMIT" >> $GENERAL_CONFIG_DIR/indy.env
-
-if [ -z \$6 ]; then
- init_indy_keys --name \$1
-else
- init_indy_keys --name \$1 --seed \$6
-fi
-EOF
-
-chmod +x /usr/local/bin/init_indy_node
-
-# add systemd script
-cat < /etc/systemd/system/indy-node.service
-[Unit]
-Description=Indy Node
-Requires=indy-node-control.service
-
-[Service]
-EnvironmentFile=$GENERAL_CONFIG_DIR/indy.env
-ExecStart=/usr/bin/env python3 -O /usr/local/bin/start_indy_node \${NODE_NAME} \${NODE_IP} \${NODE_PORT} \${NODE_CLIENT_IP} \${NODE_CLIENT_PORT}
-User=indy
-Group=indy
-Restart=on-failure
-RestartSec=10
-StartLimitBurst=10
-StartLimitInterval=200
-TimeoutSec=300
-LimitNOFILE=$NOFILES_SOFT_LIMIT:$NOFILES_HARD_LIMIT
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-
-cat < /etc/systemd/system/indy-node-control.service
-[Unit]
-Description=Service for upgrade of existing Indy Node and other operations
-#Requires=indy.service
-#After=indy.service
-After=network.target
-
-[Service]
-Type=simple
-EnvironmentFile=$GENERAL_CONFIG_DIR/node_control.conf
-ExecStart=/usr/bin/env python3 -O /usr/local/bin/start_node_control_tool \$TEST_MODE --hold-ext \${HOLD_EXT}
-Restart=on-failure
-RestartSec=10
-StartLimitBurst=10
-StartLimitInterval=200
-TimeoutSec=300
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-# add supervisord script
-cat < /etc/supervisor/indy-node.conf
-[supervisord]
-nodaemon=true
-logfile=/var/log/indy/supervisord.log
-logfile_maxbytes=10MB
-loglevel=critical
-
-[supervisorctl]
-serverurl=http://127.0.0.1:9001
-
-[inet_http_server]
-port = 127.0.0.1:9001
-
-[rpcinterface:supervisor]
-supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
-
-[program:indy-node]
-command=sh -ac '. $GENERAL_CONFIG_DIR/indy.env;/usr/bin/env python3 -O /usr/local/bin/start_indy_node \${NODE_NAME} \${NODE_IP} \${NODE_PORT} \${NODE_CLIENT_IP} \${NODE_CLIENT_PORT}'
-user=indy
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-autorestart=true
-startsecs=15
-startretries=6
-stopasgroup=true
-killasgroup=true
-
-[program:indy-node-control]
-command=sh -ac '. $GENERAL_CONFIG_DIR/node_control.conf;/usr/bin/env python3 -O /usr/local/bin/start_node_control_tool \${TEST_MODE} --hold-ext "\${HOLD_EXT}"'
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-autorestart=true
-startsecs=15
-startretries=6
-stopasgroup=true
-killasgroup=true
-EOF
-
-HOLD_EXT_ADDED=$(grep HOLD_EXT /etc/indy/node_control.conf)
-if [ ! -f $GENERAL_CONFIG_DIR/node_control.conf ] || [ -z "${HOLD_EXT_ADDED}" ]; then
- cat < $GENERAL_CONFIG_DIR/node_control.conf
-# Uncomment this to run agent in test mode:
-#TEST_MODE=--test
-
-TEST_MODE=
-HOLD_EXT=
-EOF
-fi
-sed -ie '/HOLD_EXT/{ s/\\//g}' $GENERAL_CONFIG_DIR/node_control.conf
-
-mv /usr/local/bin/upgrade_indy_node_ubuntu1604.sh /usr/local/bin/upgrade_indy_node
-mv /usr/local/bin/upgrade_indy_node_ubuntu1604_test.sh /usr/local/bin/upgrade_indy_node_test
-mv /usr/local/bin/restart_indy_node_ubuntu1604.sh /usr/local/bin/restart_indy_node
-mv /usr/local/bin/restart_sovrin_node_ubuntu1604.sh /usr/local/bin/restart_sovrin_node
-mv /usr/local/bin/complete_rebranding_upgrade_ubuntu1604.sh /usr/local/bin/complete_rebranding_upgrade
-
-chmod +x /usr/local/bin/upgrade_indy_node
-chmod +x /usr/local/bin/upgrade_indy_node_test
-chmod +x /usr/local/bin/restart_indy_node
-chmod +x /usr/local/bin/restart_sovrin_node
-chmod +x /usr/local/bin/complete_rebranding_upgrade
-
-rm -f /usr/local/bin/delete_indy_node.bat /usr/local/bin/upgrade_indy_node_test.bat \
- /usr/local/bin/restart_indy_node.bat /usr/local/bin/install_nssm.bat /usr/local/bin/upgrade_indy_node.bat \
- /usr/local/bin/install_indy_node.bat /usr/local/bin/restart_upgrade_agent.bat
-
-chown -R indy:indy $GENERAL_CONFIG_DIR
-chown -R indy:indy $GENERAL_DATA_DIR
-chown -R indy:indy $GENERAL_LOG_DIR
-chmod -R ug+rw $GENERAL_CONFIG_DIR
-chmod -R ug+rw $GENERAL_DATA_DIR
-chmod -R ug+rw $GENERAL_LOG_DIR
-
-# Automatically added from template:
-if which py3compile >/dev/null 2>&1; then
- py3compile -O -p indy-node $INSTALL_DIR
-fi
-
-# End automatically added section
diff --git a/build-scripts/ubuntu-1604/preinst_node b/build-scripts/ubuntu-1604/preinst_node
deleted file mode 100755
index 4e1addfb6..000000000
--- a/build-scripts/ubuntu-1604/preinst_node
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-if ! id -u indy > /dev/null 2>&1; then
- useradd -r -m -s /bin/bash -U indy
-fi
diff --git a/build-scripts/ubuntu-1604/prepare-package.sh b/build-scripts/ubuntu-1604/prepare-package.sh
deleted file mode 100755
index 50d827506..000000000
--- a/build-scripts/ubuntu-1604/prepare-package.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/bash -xe
-
-if [ "$1" = "--help" ] ; then
- echo "Usage: $0 "
- echo " - Set to 'debian-packages' when preparing deb packages, and 'python-packages' when preparing PyPi packages."
- exit 0
-fi
-
-repo="$1"
-module_name="$2"
-version_dotted="$3"
-distro_packages="$4"
-
-BUMP_SH_SCRIPT="bump_version.sh"
-GENERATE_MANIFEST_SCRIPT="generate_manifest.sh"
-
-pushd $repo
-
-echo -e "\nSetting version to $version_dotted"
-bash -ex $BUMP_SH_SCRIPT $version_dotted
-cat $module_name/__version__.json
-
-echo -e "\nGenerating manifest"
-bash -ex $GENERATE_MANIFEST_SCRIPT
-cat $module_name/__manifest__.json
-
-echo -e "\n\nPrepares indy-node debian package version"
-sed -i -r "s~indy-node==([0-9\.]+[0-9])(\.)?([a-z]+)~indy-node==\1\~\3~" setup.py
-
-if [ "$distro_packages" = "debian-packages" ]; then
- # Only used for the deb package builds, NOT for the PyPi package builds.
- # Update the package names to match the versions that are pre-installed on the os.
- echo -e "\nAdapt the dependencies for the Canonical archive"
- #### ToDo adjust packages for the Cannonical archive for Ubuntu 20.04 (focal)
- # sed -i "s~timeout-decorator~python3-timeout-decorator~" setup.py
- # sed -i "s~distro~python3-distro~" setup.py
-elif [ "$distro_packages" = "python-packages" ]; then
- echo -e "\nNo adaption of dependencies for python packages"
-else
- echo -e "\nNo distribution specified. Please, specify distribution as 'debian-packages' or 'python-packages'."
- exit 1
-fi
-
-echo "Preparing config files"
-GENERAL_CONFIG_DIR="\/etc\/indy"
-REPO_GENERAL_CONFIG_DIR="indy_node/general_config"
-# Define user config directory
-sed -i "s/^\(GENERAL_CONFIG_DIR\s*=\s*\).*\$/\1\"$GENERAL_CONFIG_DIR\"/" indy_common/config.py
-# Create user config
-cp $REPO_GENERAL_CONFIG_DIR/general_config.py $REPO_GENERAL_CONFIG_DIR/indy_config.py
-cat $REPO_GENERAL_CONFIG_DIR/ubuntu_platform_config.py >> $REPO_GENERAL_CONFIG_DIR/indy_config.py
-rm -f $REPO_GENERAL_CONFIG_DIR/general_config.py
-rm -f $REPO_GENERAL_CONFIG_DIR/ubuntu_platform_config.py
-rm -f $REPO_GENERAL_CONFIG_DIR/windows_platform_config.py
-
-popd
-
-echo -e "\nFinished preparing $repo for publishing\n"
diff --git a/build-scripts/ubuntu-1604/prerm b/build-scripts/ubuntu-1604/prerm
deleted file mode 100755
index 40af9b22a..000000000
--- a/build-scripts/ubuntu-1604/prerm
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-# Automatically added from template:
-
-dpkg -L {package_name} | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)'
-
-# End automatically added section
\ No newline at end of file
diff --git a/build-scripts/ubuntu-2004/build-indy-node.sh b/build-scripts/ubuntu-2004/build-indy_node.sh
similarity index 100%
rename from build-scripts/ubuntu-2004/build-indy-node.sh
rename to build-scripts/ubuntu-2004/build-indy_node.sh
From 4b3739350ad378f52a90e854876fdc8e515d2580 Mon Sep 17 00:00:00 2001
From: pSchlarb <87540518+pSchlarb@users.noreply.github.com>
Date: Thu, 7 Apr 2022 16:19:33 +0000
Subject: [PATCH 02/10] Update Version number for v1.14.0rc1
Signed-off-by: pSchlarb <87540518+pSchlarb@users.noreply.github.com>
---
indy_node/__version__.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/indy_node/__version__.json b/indy_node/__version__.json
index 1319e6fe2..822555dcb 100644
--- a/indy_node/__version__.json
+++ b/indy_node/__version__.json
@@ -1 +1 @@
-[1, 13, 0, "dev", 0]
+[1, 14, 0, "rc", 1]
From 3f3e6c6c318eb08bf18444e96433eebb4d162e92 Mon Sep 17 00:00:00 2001
From: pSchlarb
Date: Wed, 20 Apr 2022 10:18:47 +0000
Subject: [PATCH 03/10] Added PlenumDependencyWF
Signed-off-by: pSchlarb
---
.github/actions/getNewNodeVersion/action.yaml | 30 +++++++++
.github/workflows/updatePlenumDependency.yaml | 66 +++++++++++++++++++
2 files changed, 96 insertions(+)
create mode 100644 .github/actions/getNewNodeVersion/action.yaml
create mode 100644 .github/workflows/updatePlenumDependency.yaml
diff --git a/.github/actions/getNewNodeVersion/action.yaml b/.github/actions/getNewNodeVersion/action.yaml
new file mode 100644
index 000000000..8376fb7a0
--- /dev/null
+++ b/.github/actions/getNewNodeVersion/action.yaml
@@ -0,0 +1,30 @@
+name: "Get New NodeVersion"
+description: "Sets version parameters and makes them available as outputs for subsequent processes."
+
+inputs:
+ isRC:
+ description: "A flag indicating whether or not this is a release candidate build; set to either 'true' or 'false'."
+ required: true
+ default: true
+
+outputs:
+ nodeVersion:
+ description: "The new Version. (Bumped Patch by 1)"
+ value: ${{ steps.versions.outputs.nodeVersion }}
+
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/checkout@v3
+ - name: Get Versions
+ id: versions
+ shell: bash
+ run: |
+ major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
+ minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
+ patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
+ if [[ "${{ inputs.isRC }}" == "true" ]]; then
+ echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
+ else
+ echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
+ fi
\ No newline at end of file
diff --git a/.github/workflows/updatePlenumDependency.yaml b/.github/workflows/updatePlenumDependency.yaml
new file mode 100644
index 000000000..79417c56c
--- /dev/null
+++ b/.github/workflows/updatePlenumDependency.yaml
@@ -0,0 +1,66 @@
+name: Update Plenum Dependency
+
+on:
+ push:
+ tags:
+ - setPlenum-v**
+
+jobs:
+ taginfos:
+ name: get Tag infos
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.get-release-info.outputs.version }}
+ isPreRelease: ${{ steps.get-release-info.outputs.isRC }}
+ Branch: ${{ steps.setPRBranch.outputs.prBranch }}
+ BASE: ${{ steps.branch.outputs.BASE}}
+ nodeVersion: ${{ steps.nodeVersion.outputs.nodeVersion}}
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v3
+ - name: extract branch
+ id: branch
+ run: |
+ raw=$(git branch -r --contains ${{ github.ref }})
+ branch=${raw/origin\/}
+ echo ::set-output\ name=BASE::$branch
+ echo "::debug::BASE is being set to $branch"
+ - name: get-release-info
+ id: get-release-info
+ uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ with:
+ versionString: "${{ github.ref }}"
+ - name: setPRBranch
+ id: setPRBranch
+ run: |
+ if [[ "${{ steps.get-release-info.outputs.isRC }}" == "true" ]]; then
+ echo ::set-output\ name=prBranch::update-plenum-rc-version
+ else
+ echo ::set-output\ name=prBranch::update-plenum-version
+ fi
+ - name: Get new Node Version
+ id: nodeVersion
+ uses: ./.github/actions/getNewNodeVersion
+ with:
+ isRC: ${{ steps.get-release-info.outputs.isRC }}
+
+ updateAndCommit:
+ runs-on: ubuntu-latest
+ needs: taginfos
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v3
+ with:
+ token: ${{ secrets.BOT_PR_PAT }}
+ - name: Update Setup.py
+ run: |
+ sed -E -i 's/indy-plenum==[[:digit:]]+.[[:digit:]]+.[[:digit:]]+(.(dev|rc)[[:digit:]]+)?/indy-plenum==${{needs.taginfos.outputs.version}}/g' setup.py
+ - name: CommitAndTag
+ uses: EndBug/add-and-commit@v9
+ with:
+ author_name: ${{ github.actor }}
+ author_email: ${{ github.event.pusher.email }}
+ commit: --signoff
+ message: 'Update Plenum Dependency to ${{needs.taginfos.outputs.version}}'
+ new_branch: ${{ needs.taginfos.outputs.Branch}}
+ tag: "setRelease-v${{needs.taginfos.outputs.nodeVersion}}"
\ No newline at end of file
From 66f1a9f0b8185e9f1b79afcb5939d1d129c6c971 Mon Sep 17 00:00:00 2001
From: pSchlarb
Date: Wed, 20 Apr 2022 10:19:06 +0000
Subject: [PATCH 04/10] Pip get_installed_distributions fix
Signed-off-by: pSchlarb
---
indy_node/__init__.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/indy_node/__init__.py b/indy_node/__init__.py
index e231f2a84..17c0aa94a 100644
--- a/indy_node/__init__.py
+++ b/indy_node/__init__.py
@@ -4,6 +4,7 @@
__author_email__, __maintainer__, __license__,
load_version, set_version, load_manifest, set_manifest
)
+import pkg_resources
PLUGIN_LEDGER_IDS = set()
PLUGIN_CLIENT_REQUEST_FIELDS = {}
From bf6fbec265b169debc0497d923563940e3cd7ab8 Mon Sep 17 00:00:00 2001
From: pSchlarb
Date: Wed, 20 Apr 2022 10:32:16 +0000
Subject: [PATCH 05/10] test old newnodeVersion
Signed-off-by: pSchlarb
---
.github/actions/getNewNodeVersion/action.yaml | 2 +-
.github/workflows/updatePlenumDependency.yaml | 26 ++++++++++++++++---
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/.github/actions/getNewNodeVersion/action.yaml b/.github/actions/getNewNodeVersion/action.yaml
index 8376fb7a0..834b79c71 100644
--- a/.github/actions/getNewNodeVersion/action.yaml
+++ b/.github/actions/getNewNodeVersion/action.yaml
@@ -5,7 +5,7 @@ inputs:
isRC:
description: "A flag indicating whether or not this is a release candidate build; set to either 'true' or 'false'."
required: true
- default: true
+ default: "true"
outputs:
nodeVersion:
diff --git a/.github/workflows/updatePlenumDependency.yaml b/.github/workflows/updatePlenumDependency.yaml
index 79417c56c..8f73bd8f8 100644
--- a/.github/workflows/updatePlenumDependency.yaml
+++ b/.github/workflows/updatePlenumDependency.yaml
@@ -38,11 +38,28 @@ jobs:
else
echo ::set-output\ name=prBranch::update-plenum-version
fi
- - name: Get new Node Version
- id: nodeVersion
- uses: ./.github/actions/getNewNodeVersion
+ - name: Set up Python
+ uses: actions/setup-python@v2
with:
- isRC: ${{ steps.get-release-info.outputs.isRC }}
+ python-version: '3.8'
+ # - name: Install deps for version change
+ # run: pip install base58
+ - name: Get New Node Version
+ id: nodeVersion
+ run: |
+ major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
+ minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
+ patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
+ if [[ "${{ inputs.isRC }}" == "true" ]]; then
+ echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
+ else
+ echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
+ fi
+ # - name: Get new Node Version
+ # id: nodeVersion
+ # uses: ./.github/actions/getNewNodeVersion
+ # with:
+ # isRC: ${{ steps.get-release-info.outputs.isRC }}
updateAndCommit:
runs-on: ubuntu-latest
@@ -62,5 +79,6 @@ jobs:
author_email: ${{ github.event.pusher.email }}
commit: --signoff
message: 'Update Plenum Dependency to ${{needs.taginfos.outputs.version}}'
+ push: "origin ${{ needs.taginfos.outputs.Branch}} --set-upstream --force"
new_branch: ${{ needs.taginfos.outputs.Branch}}
tag: "setRelease-v${{needs.taginfos.outputs.nodeVersion}}"
\ No newline at end of file
From 814ba493e37c404cd79b5bf30e5f7acf4ba32291 Mon Sep 17 00:00:00 2001
From: pSchlarb
Date: Wed, 20 Apr 2022 11:34:40 +0000
Subject: [PATCH 06/10] getNodeVersionAction
Signed-off-by: pSchlarb
---
.github/actions/getNewNodeVersion/action.yaml | 4 ++
.github/workflows/updatePlenumDependency.yaml | 40 +++++++++----------
2 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/.github/actions/getNewNodeVersion/action.yaml b/.github/actions/getNewNodeVersion/action.yaml
index 834b79c71..1a8b1d073 100644
--- a/.github/actions/getNewNodeVersion/action.yaml
+++ b/.github/actions/getNewNodeVersion/action.yaml
@@ -16,6 +16,10 @@ runs:
using: "composite"
steps:
- uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
- name: Get Versions
id: versions
shell: bash
diff --git a/.github/workflows/updatePlenumDependency.yaml b/.github/workflows/updatePlenumDependency.yaml
index 8f73bd8f8..70b8f92c9 100644
--- a/.github/workflows/updatePlenumDependency.yaml
+++ b/.github/workflows/updatePlenumDependency.yaml
@@ -38,28 +38,26 @@ jobs:
else
echo ::set-output\ name=prBranch::update-plenum-version
fi
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: '3.8'
- # - name: Install deps for version change
- # run: pip install base58
- - name: Get New Node Version
- id: nodeVersion
- run: |
- major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
- minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
- patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
- if [[ "${{ inputs.isRC }}" == "true" ]]; then
- echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
- else
- echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
- fi
- # - name: Get new Node Version
- # id: nodeVersion
- # uses: ./.github/actions/getNewNodeVersion
+ # - name: Set up Python
+ # uses: actions/setup-python@v2
# with:
- # isRC: ${{ steps.get-release-info.outputs.isRC }}
+ # python-version: '3.8'
+ # - name: Get New Node Version
+ # id: nodeVersion
+ # run: |
+ # major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
+ # minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
+ # patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
+ # if [[ "${{ inputs.isRC }}" == "true" ]]; then
+ # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
+ # else
+ # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
+ # fi
+ - name: Get new Node Version
+ id: nodeVersion
+ uses: ./.github/actions/getNewNodeVersion
+ with:
+ isRC: ${{ steps.get-release-info.outputs.isRC }}
updateAndCommit:
runs-on: ubuntu-latest
From f63ff840649ac1c51158d45ba98f80329244ebcb Mon Sep 17 00:00:00 2001
From: Philipp Schlarb
Date: Tue, 10 May 2022 15:41:30 +0200
Subject: [PATCH 07/10] fixed references, Release Workflow Diagram Polishing
for PR
Signed-off-by: Philipp Schlarb
---
.github/workflows/{push_pr.yaml => PR.yaml} | 17 ++-
.github/workflows/Push.yaml | 75 ++++++++++++
.github/workflows/README.md | 20 ++--
.../workflows/WIPupdatePlenumDependency.yaml | 83 +++++++++++++
.../workflows/build/Dockerfile.ubuntu-1604 | 30 -----
.github/workflows/buildimage.yaml | 75 ------------
.github/workflows/buildpackages.yaml | 111 ------------------
.github/workflows/publishRelease.yaml | 6 +-
.github/workflows/publish_artifacts.yaml | 83 -------------
.github/workflows/releasepr.yaml | 10 +-
.github/workflows/tag.yaml | 2 +-
.github/workflows/updatePlenumDependency.yaml | 82 -------------
docs/source/release-workflow.png | Bin 0 -> 146883 bytes
docs/source/release-workflow.puml | 81 +++++++++++++
indy_node/__init__.py | 1 -
indy_node/__version__.json | 2 +-
16 files changed, 265 insertions(+), 413 deletions(-)
rename .github/workflows/{push_pr.yaml => PR.yaml} (82%)
create mode 100644 .github/workflows/Push.yaml
create mode 100644 .github/workflows/WIPupdatePlenumDependency.yaml
delete mode 100644 .github/workflows/build/Dockerfile.ubuntu-1604
delete mode 100644 .github/workflows/buildimage.yaml
delete mode 100644 .github/workflows/buildpackages.yaml
delete mode 100644 .github/workflows/publish_artifacts.yaml
delete mode 100644 .github/workflows/updatePlenumDependency.yaml
create mode 100644 docs/source/release-workflow.png
create mode 100644 docs/source/release-workflow.puml
diff --git a/.github/workflows/push_pr.yaml b/.github/workflows/PR.yaml
similarity index 82%
rename from .github/workflows/push_pr.yaml
rename to .github/workflows/PR.yaml
index d152758e3..8daa03daa 100644
--- a/.github/workflows/push_pr.yaml
+++ b/.github/workflows/PR.yaml
@@ -1,14 +1,11 @@
name: Indy Node - Push and PR Workflow
on:
- push:
- branches:
- - ubuntu-20.04-upgrade
- - feature/did-indy*
-
pull_request:
branches:
- ubuntu-20.04-upgrade
- feature/did-indy*
+ paths:
+ - '**.py'
workflow_dispatch:
jobs:
@@ -30,16 +27,16 @@ jobs:
uses: actions/checkout@v2
- name: setup
id: setup
- uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/workflow-setup@main
lint:
name: Lint
- uses: pschlarb/indy-shared-gha/.github/workflows/lint.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/lint.yaml@main
build-image:
name: Create Builder Image
needs: [workflow-setup, lint]
- uses: pschlarb/indy-shared-gha/.github/workflows/buildimage.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildimage.yaml@main
with:
CACHE_KEY_BUILD: ${{ needs.workflow-setup.outputs.CACHE_KEY_BUILD }}
DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build
@@ -56,7 +53,7 @@ jobs:
build_packages:
name: Build Packages
needs: [workflow-setup, indy_node_tests]
- uses: pschlarb/indy-shared-gha/.github/workflows/buildpackages.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildpackages.yaml@main
with:
DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ needs.release-infos.outputs.UBUNTU_VERSION }}
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
@@ -68,7 +65,7 @@ jobs:
name: Publish Artifacts
needs: [workflow-setup, build_packages]
if: needs.workflow-setup.outputs.publish == 'true'
- uses: pschlarb/indy-shared-gha/.github/workflows/publish_artifacts.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/publish_artifacts.yaml@main
with:
COMPONENT: 'dev'
UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
diff --git a/.github/workflows/Push.yaml b/.github/workflows/Push.yaml
new file mode 100644
index 000000000..13126bda9
--- /dev/null
+++ b/.github/workflows/Push.yaml
@@ -0,0 +1,75 @@
+name: Indy Node - Push and PR Workflow
+on:
+ push:
+ branches:
+ - ubuntu-20.04-upgrade
+ - feature/did-indy*
+ paths:
+ - '**.py'
+
+jobs:
+ workflow-setup:
+ name: Initialize Workflow
+ runs-on: ubuntu-latest
+ outputs:
+ CACHE_KEY_BUILD: ${{ steps.setup.outputs.CACHE_KEY_BUILD }}
+ UBUNTU_VERSION: ${{ steps.setup.outputs.UBUNTU_VERSION }}
+ # Expose the lowercase version of the GitHub repository name
+ # to all subsequent jobs that reference image repositories
+ # as the push and pull operations require the URL of the repository
+ # to be in lowercase.
+ GITHUB_REPOSITORY_NAME: ${{ steps.setup.outputs.GITHUB_REPOSITORY_NAME }}
+ distribution: ${{ steps.setup.outputs.distribution }}
+ publish: ${{ steps.setup.outputs.publish }}
+ steps:
+ - name: checkout source code
+ uses: actions/checkout@v2
+ - name: setup
+ id: setup
+ uses: hyperledger/indy-shared-gha/.github/actions/workflow-setup@main
+
+ lint:
+ name: Lint
+ uses: hyperledger/indy-shared-gha/.github/workflows/lint.yaml@main
+
+ build-image:
+ name: Create Builder Image
+ needs: [workflow-setup, lint]
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildimage.yaml@main
+ with:
+ CACHE_KEY_BUILD: ${{ needs.workflow-setup.outputs.CACHE_KEY_BUILD }}
+ DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build
+ UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
+
+ indy_node_tests:
+ name: Indy Node Tests
+ needs: [workflow-setup, build-image]
+ uses: ./.github/workflows/reuseable_test.yaml
+ with:
+ GITHUB_REPOSITORY_NAME: ${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}
+ UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
+
+ build_packages:
+ name: Build Packages
+ needs: [workflow-setup, indy_node_tests]
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildpackages.yaml@main
+ with:
+ DOCKER_IMAGE: ghcr.io/${{ needs.workflow-setup.outputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ needs.release-infos.outputs.UBUNTU_VERSION }}
+ UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
+ isDev: true
+ isRC: false
+ moduleName: indy_node
+
+ publish_artifacts:
+ name: Publish Artifacts
+ needs: [workflow-setup, build_packages]
+ if: needs.workflow-setup.outputs.publish == 'true'
+ uses: hyperledger/indy-shared-gha/.github/workflows/publish_artifacts.yaml@main
+ with:
+ COMPONENT: 'dev'
+ UBUNTU_VERSION: ${{ needs.workflow-setup.outputs.UBUNTU_VERSION }}
+ distribution: ${{ needs.workflow-setup.outputs.distribution }}
+ moduleName: indy_node
+ secrets:
+ INDY_ARTIFACTORY_REPO_CONFIG: ${{ secrets.INDY_ARTIFACTORY_REPO_CONFIG }}
+ PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
index 05c141f22..a7db6f885 100644
--- a/.github/workflows/README.md
+++ b/.github/workflows/README.md
@@ -1,13 +1,11 @@
-# GitHub Actions Workflow
+# GitHub Actions Workflows
-The workflow in the [push_pr.yaml](push_pr.yaml) file runs on push and pull requests to the ubuntu-20-04-upgrade branch.
-It uses the following reusable workflows in this folder.
+The [PR](PR.yaml) workflow runs on Pull Requests to the ubuntu-20.04-upgrade branch,
+which only contain changes to python files. If no python file is affected it doesn't run.
+The same applies to the [Push](Push.yaml) workflow respectively for pushes.
-+ [buildimage.yaml](buildimage.yaml)
- This workflow builds the dockerimages and pushes them to the GHCR.
-+ [test.yaml](test.yaml)
- This workflow runs the tests inside the uploaded docker images.
-+ [buildpackages.yaml](buildpackages.yaml)
- This workflows builds the python and debian packages. It also uploads them to the workflow.
-+ [publish_artifacts.yaml](publish_artifacts.yaml)
- This workflow uploads the packages to PYPI and Artifactory.
\ No newline at end of file
+The [tag](tag.yaml), [releasepr](releasepr.yaml) and [publishRelease](publishRelease.yaml) workflows are used for the new [Release Workflow](../../docs/release-workflow.png).
+They use reuseable workflows from the [indy-shared-gha](https://github.com/hyperledger) repository and the following workflow in this folder.
+
++ [reuseable_test.yaml](reuseable_test.yaml)
+ This workflow runs the tests inside the uploaded docker images.
\ No newline at end of file
diff --git a/.github/workflows/WIPupdatePlenumDependency.yaml b/.github/workflows/WIPupdatePlenumDependency.yaml
new file mode 100644
index 000000000..1cac61b41
--- /dev/null
+++ b/.github/workflows/WIPupdatePlenumDependency.yaml
@@ -0,0 +1,83 @@
+# WIP to Update node after a plenum update has occured
+# name: Update Plenum Dependency
+
+# on:
+# push:
+# tags:
+# - setPlenum-v**
+
+# jobs:
+# taginfos:
+# name: get Tag infos
+# runs-on: ubuntu-latest
+# outputs:
+# version: ${{ steps.get-release-info.outputs.version }}
+# isPreRelease: ${{ steps.get-release-info.outputs.isRC }}
+# Branch: ${{ steps.setPRBranch.outputs.prBranch }}
+# BASE: ${{ steps.branch.outputs.BASE}}
+# nodeVersion: ${{ steps.nodeVersion.outputs.nodeVersion}}
+# steps:
+# - name: checkout source code
+# uses: actions/checkout@v3
+# - name: extract branch
+# id: branch
+# run: |
+# raw=$(git branch -r --contains ${{ github.ref }})
+# branch=${raw/origin\/}
+# echo ::set-output\ name=BASE::$branch
+# echo "::debug::BASE is being set to $branch"
+# - name: get-release-info
+# id: get-release-info
+# uses: hyperledger/indy-shared-gha/.github/actions/get-release-info@main
+# with:
+# versionString: "${{ github.ref }}"
+# - name: setPRBranch
+# id: setPRBranch
+# run: |
+# if [[ "${{ steps.get-release-info.outputs.isRC }}" == "true" ]]; then
+# echo ::set-output\ name=prBranch::update-plenum-rc-version
+# else
+# echo ::set-output\ name=prBranch::update-plenum-version
+# fi
+# # - name: Set up Python
+# # uses: actions/setup-python@v2
+# # with:
+# # python-version: '3.8'
+# # - name: Get New Node Version
+# # id: nodeVersion
+# # run: |
+# # major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
+# # minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
+# # patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
+# # if [[ "${{ inputs.isRC }}" == "true" ]]; then
+# # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
+# # else
+# # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
+# # fi
+# - name: Get new Node Version
+# id: nodeVersion
+# uses: ./.github/actions/getNewNodeVersion
+# with:
+# isRC: ${{ steps.get-release-info.outputs.isRC }}
+
+# updateAndCommit:
+# runs-on: ubuntu-latest
+# needs: taginfos
+# steps:
+# - name: checkout source code
+# uses: actions/checkout@v3
+# with:
+# token: ${{ secrets.BOT_PR_PAT }}
+# - name: Update Setup.py
+# run: |
+# sed -E -i 's/indy-plenum==[[:digit:]]+.[[:digit:]]+.[[:digit:]]+(.(dev|rc)[[:digit:]]+)?/indy-plenum==${{needs.taginfos.outputs.version}}/g' setup.py
+# - name: CommitAndTag
+# uses: EndBug/add-and-commit@v9
+# with:
+# author_name: ${{ github.actor }}
+# author_email: ${{ github.event.pusher.email }}
+# commit: --signoff
+# message: 'Update Plenum Dependency to ${{needs.taginfos.outputs.version}}'
+# push: "origin ${{ needs.taginfos.outputs.Branch}} --set-upstream --force"
+# new_branch: ${{ needs.taginfos.outputs.Branch}}
+# tag: "setRelease-v${{needs.taginfos.outputs.nodeVersion}}"
\ No newline at end of file
diff --git a/.github/workflows/build/Dockerfile.ubuntu-1604 b/.github/workflows/build/Dockerfile.ubuntu-1604
deleted file mode 100644
index 898d7b430..000000000
--- a/.github/workflows/build/Dockerfile.ubuntu-1604
+++ /dev/null
@@ -1,30 +0,0 @@
-FROM hyperledger/indy-core-baseci:0.0.4
-
-LABEL maintainer="Hyperledger "
-
-RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 \
- && apt-get update -y \
- && apt-get install -y \
- python3-nacl \
- libindy-crypto=0.4.5 \
- libindy=1.15.0~1625-xenial \
-# rocksdb python wrapper
- libbz2-dev \
- zlib1g-dev \
- liblz4-dev \
- libsnappy-dev \
- rocksdb=5.8.8 \
- ursa=0.3.2-2 \
-# Build dependencies
- ruby \
- ruby-dev \
- rubygems \
- gcc \
- make \
-# zstd is needed for caching in github actions pipeline
- zstd
-
-# install fpm
-RUN gem install --no-ri --no-rdoc rake fpm
-
-RUN indy_image_clean
\ No newline at end of file
diff --git a/.github/workflows/buildimage.yaml b/.github/workflows/buildimage.yaml
deleted file mode 100644
index 9b4b110c2..000000000
--- a/.github/workflows/buildimage.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: "Build Docker Image"
-
-on:
- workflow_call:
- inputs:
- CACHE_KEY_BUILD:
- required: true
- type: string
- GITHUB_REPOSITORY_NAME:
- required: true
- type: string
- UBUNTU_VERSION:
- required: true
- type: string
-
-jobs:
- build-image:
- name: Create Builder Image
- runs-on: ubuntu-latest
- env:
- CACHE_KEY_BUILD: ${{ inputs.CACHE_KEY_BUILD }}
- GITHUB_REPOSITORY_NAME: ${{ inputs.GITHUB_REPOSITORY_NAME }}
- UBUNTU_VERSION: ${{ inputs.UBUNTU_VERSION }}
- steps:
- - name: Git checkout
- uses: actions/checkout@v2
-
- - name: Try load from cache
- id: cache-image
- uses: actions/cache@v2
- with:
- path: ${GITHUB_WORKSPACE}/cache
- key: ${{ env.CACHE_KEY_BUILD}}
-
- - name: Prepare image labels and tags
- if: steps.cache-image.outputs.cache-hit != 'true'
- id: prep
- shell: bash
- run: |
- DOCKER_IMAGE=ghcr.io/${{ env.GITHUB_REPOSITORY_NAME }}/node-build
- TAGS="${DOCKER_IMAGE}:latest,${DOCKER_IMAGE}:${{ env.UBUNTU_VERSION }}"
- echo ::set-output name=tags::${TAGS}
- echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
-
- - name: Log into the GitHub Container Registry
- if: steps.cache-image.outputs.cache-hit != 'true'
- uses: docker/login-action@v1
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Set up Docker Buildx
- if: steps.cache-image.outputs.cache-hit != 'true'
- uses: docker/setup-buildx-action@v1
-
- - name: Build and push image
- if: steps.cache-image.outputs.cache-hit != 'true'
- uses: docker/build-push-action@v2
- with:
- context: .
- file: .github/workflows/build/Dockerfile.${{ env.UBUNTU_VERSION }}
- no-cache: true
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.prep.outputs.tags }}
- labels: |
- org.opencontainers.image.source=${{ github.event.repository.html_url }}
- org.opencontainers.image.created=${{ steps.prep.outputs.created }}
- org.opencontainers.image.revision=${{ github.sha }}
-
- - name: Touch Cache
- if: steps.cache-image.outputs.cache-hit != 'true'
- run: |
- mkdir -p ${GITHUB_WORKSPACE}/cache
- touch ${GITHUB_WORKSPACE}/cache/${{ env.CACHE_KEY_BUILD }}
\ No newline at end of file
diff --git a/.github/workflows/buildpackages.yaml b/.github/workflows/buildpackages.yaml
deleted file mode 100644
index a5e82d926..000000000
--- a/.github/workflows/buildpackages.yaml
+++ /dev/null
@@ -1,111 +0,0 @@
-name: "Build Node Packages"
-
-on:
- workflow_call:
- inputs:
- GITHUB_REPOSITORY_NAME:
- required: true
- type: string
- UBUNTU_VERSION:
- required: true
- type: string
- isDev:
- required: true
- type: string
- isRC:
- required: true
- type: string
-
-jobs:
- build_release:
- name: Build Release
- runs-on: ubuntu-20.04
- env:
- UBUNTU_VERSION: ${{ inputs.UBUNTU_VERSION }}
- container:
- image: ghcr.io/${{ inputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ inputs.UBUNTU_VERSION }}
- steps:
- - name: Check out code
- uses: actions/checkout@v1
-
- - name: Set Build Version
- id: version
- uses: ./.github/actions/set-version
- with:
- moduleName: indy_node
- isDev: ${{ inputs.isDev }}
- isRC: ${{ inputs.isRC }}
-
- - name: Build Deployment Package
- run: |
- mkdir -p /tmp/node-build
- ./build-scripts/${{ env.UBUNTU_VERSION }}/build-indy-node.sh "/__w/indy-node/indy-node" "${{ steps.version.outputs.upstreamVer }}" "/tmp/node-build" "${{ steps.version.outputs.pkgVer }}"
-
- - uses: actions/upload-artifact@v2
- with:
- name: node-deb
- path: /tmp/node-build
- retention-days: 5
-
- build_3rd_party_dependencies:
- name: Build 3rd Party Dependencies
- runs-on: ubuntu-20.04
- env:
- UBUNTU_VERSION: ${{ inputs.UBUNTU_VERSION }}
- container:
- image: ghcr.io/${{ inputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ inputs.UBUNTU_VERSION }}
- steps:
- - name: Check out code
- uses: actions/checkout@v1
-
- - name: Try load from cache.
- id: third-party-dependencies
- uses: actions/cache@v2
- with:
- path: /tmp/third-party-dependencies
- key: ${{ format('third-party-dependencies-{0}', hashFiles(format('./build-scripts/{0}/build-3rd-parties.sh', inputs.UBUNTU_VERSION ))) }}
-
- - name: Build 3rd party deployment packages
- if: steps.third-party-dependencies.outputs.cache-hit != 'true'
- run: |
- mkdir -p ./build-scripts/${{ env.UBUNTU_VERSION }}/cache/3rd-party-dependencies/
- ./build-scripts/${{ env.UBUNTU_VERSION }}/build-3rd-parties.sh ./cache/3rd-party-dependencies
- mv ./build-scripts/${{ env.UBUNTU_VERSION }}/cache/* /tmp/third-party-dependencies
-
- build-python-packages:
- name: Build Python Packages
- runs-on: ubuntu-20.04
- steps:
- - name: Check out code
- uses: actions/checkout@v1
-
- - name: Set up Python 3.8
- uses: actions/setup-python@v2
- with:
- python-version: 3.8
-
- - name: Install required packages via pip
- run: |
- python3 -m pip install pytest-runner wheel
-
- - name: Set Build Version
- id: version
- uses: ./.github/actions/set-version
- with:
- moduleName: indy_node
- isDev: ${{ inputs.isDev }}
- isRC: ${{ inputs.isRC }}
-
- - name: Prepare package and set version
- run: |
- ./build-scripts/${{ inputs.UBUNTU_VERSION }}/prepare-package.sh . indy_node "${{ steps.version.outputs.upstreamVer }}" python-packages
-
- - name: Building python package
- run: |
- python3 setup.py sdist --dist-dir /tmp/dist bdist_wheel --dist-dir /tmp/dist
-
- - uses: actions/upload-artifact@v2
- with:
- name: node-python
- path: /tmp/dist
- retention-days: 5
diff --git a/.github/workflows/publishRelease.yaml b/.github/workflows/publishRelease.yaml
index 7753c0aa3..ec77e9df1 100644
--- a/.github/workflows/publishRelease.yaml
+++ b/.github/workflows/publishRelease.yaml
@@ -32,12 +32,12 @@ jobs:
uses: actions/checkout@v2
- name: get-release-info
id: get-release-info
- uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/get-release-info@main
with:
versionString: "${{ github.event.head_commit.message }}"
- name: workflow-setup
id: workflow-setup
- uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/workflow-setup@main
createRelease:
name: Create Release
@@ -109,7 +109,7 @@ jobs:
name: Publish Artifacts
needs: [release-infos, createRelease]
if: needs.release-infos.outputs.isVersionBump == 'true'
- uses: pschlarb/indy-shared-gha/.github/workflows/publish_artifacts.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/publish_artifacts.yaml@main
with:
COMPONENT: ${{ needs.release-infos.component }}
UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
diff --git a/.github/workflows/publish_artifacts.yaml b/.github/workflows/publish_artifacts.yaml
deleted file mode 100644
index cb7aa2c4c..000000000
--- a/.github/workflows/publish_artifacts.yaml
+++ /dev/null
@@ -1,83 +0,0 @@
-name: "Publish Artifacts"
-
-on:
- workflow_call:
- inputs:
- GITHUB_REF:
- required: true
- type: string
- UBUNTU_VERSION:
- required: true
- type: string
- distribution:
- required: true
- type: string
- secrets:
- INDY_ARTIFACTORY_REPO_CONFIG:
- required: true
- PYPI_API_TOKEN:
- required: true
-
-
-jobs:
- publish_artifacts:
- name: Publish Artifacts
- runs-on: ubuntu-20.04
- env:
- GITHUB_REF: ${{ inputs.GITHUB_REF }}
- distribution: ${{ inputs.distribution }}
- steps:
- - name: Check out code
- uses: actions/checkout@v1
-
- - name: Setup JFrog CLI
- uses: jfrog/setup-jfrog-cli@v2
- env:
- JF_ARTIFACTORY_1: ${{ secrets.INDY_ARTIFACTORY_REPO_CONFIG }}
-
- - name: Ping Artifactory
- run: |
- # Test the connection to Ping the Hyperledger Artifactory server
- # to ensure everything has been setup correctly.
- jfrog rt ping
-
- - name: Download Node Artifacts from Pipeline Artifacts
- uses: actions/download-artifact@v2
- with:
- name: node-deb
- path: to_publish
-
- - name: Publish Node Artifacts
- uses: ./.github/actions/publish-deb
- with:
- sourceDirectory: /home/runner/work/indy-node/indy-node/to_publish
- distribution: ${{ env.distribution }}
- component: ${{ env.GITHUB_REF }}
-
- - name: Download 3rd Party Artifacts Dependencies from Cache
- id: third-party-dependencies
- uses: actions/cache@v2
- with:
- path: /tmp/third-party-dependencies
- key: ${{ format('third-party-dependencies-{0}', hashFiles(format('./build-scripts/{0}/build-3rd-parties.sh', inputs.UBUNTU_VERSION ))) }}
-
- - name: Publish 3rd Party Dependencies
- uses: ./.github/actions/publish-deb
- with:
- sourceDirectory: /home/runner/tmp/third-party-dependencies
- distribution: ${{ env.distribution }}
- component: ${{ env.GITHUB_REF }}
-
- - name: Download Python Packages from Pipeline Artifacts
- uses: actions/download-artifact@v2
- with:
- name: node-python
- path: dist
-
- - name: Publish Python Package to PyPI
- uses: pypa/gh-action-pypi-publish@release/v1
- with:
- user: __token__
- password: ${{ secrets.PYPI_API_TOKEN }}
- skip_existing: true
-
\ No newline at end of file
diff --git a/.github/workflows/releasepr.yaml b/.github/workflows/releasepr.yaml
index 26b4adffa..42e136c33 100644
--- a/.github/workflows/releasepr.yaml
+++ b/.github/workflows/releasepr.yaml
@@ -26,23 +26,23 @@ jobs:
uses: actions/checkout@v2
- name: get-release-info
id: get-release-info
- uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/get-release-info@main
with:
versionString: "${{ github.event.pull_request.body }}"
- name: workflow-setup
id: workflow-setup
- uses: pschlarb/indy-shared-gha/.github/actions/workflow-setup@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/workflow-setup@main
lint:
name: Lint
needs: [release-infos]
if: needs.release-infos.outputs.isVersionBump == 'true'
- uses: pschlarb/indy-shared-gha/.github/workflows/lint.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/lint.yaml@main
build-image:
name: Create Builder Image
needs: [release-infos, lint]
- uses: pschlarb/indy-shared-gha/.github/workflows/buildimage.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildimage.yaml@main
with:
CACHE_KEY_BUILD: ${{ needs.release-infos.outputs.CACHE_KEY_BUILD }}
DOCKER_IMAGE: ghcr.io/${{ needs.release-infos.outputs.GITHUB_REPOSITORY_NAME }}/node-build
@@ -62,7 +62,7 @@ jobs:
name: Build Packages
needs: [release-infos, indy_node_tests]
if: needs.release-infos.outputs.isVersionBump == 'true'
- uses: pschlarb/indy-shared-gha/.github/workflows/buildpackages.yaml@parametrization
+ uses: hyperledger/indy-shared-gha/.github/workflows/buildpackages.yaml@main
with:
DOCKER_IMAGE: ghcr.io/${{ needs.release-infos.outputs.GITHUB_REPOSITORY_NAME }}/node-build:${{ needs.release-infos.outputs.UBUNTU_VERSION }}
UBUNTU_VERSION: ${{ needs.release-infos.outputs.UBUNTU_VERSION }}
diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml
index 201d83d7a..98bdfef56 100644
--- a/.github/workflows/tag.yaml
+++ b/.github/workflows/tag.yaml
@@ -26,7 +26,7 @@ jobs:
echo "::debug::BASE is being set to $branch"
- name: get-release-info
id: get-release-info
- uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
+ uses: hyperledger/indy-shared-gha/.github/actions/get-release-info@main
with:
versionString: "${{ github.ref }}"
diff --git a/.github/workflows/updatePlenumDependency.yaml b/.github/workflows/updatePlenumDependency.yaml
deleted file mode 100644
index 70b8f92c9..000000000
--- a/.github/workflows/updatePlenumDependency.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-name: Update Plenum Dependency
-
-on:
- push:
- tags:
- - setPlenum-v**
-
-jobs:
- taginfos:
- name: get Tag infos
- runs-on: ubuntu-latest
- outputs:
- version: ${{ steps.get-release-info.outputs.version }}
- isPreRelease: ${{ steps.get-release-info.outputs.isRC }}
- Branch: ${{ steps.setPRBranch.outputs.prBranch }}
- BASE: ${{ steps.branch.outputs.BASE}}
- nodeVersion: ${{ steps.nodeVersion.outputs.nodeVersion}}
- steps:
- - name: checkout source code
- uses: actions/checkout@v3
- - name: extract branch
- id: branch
- run: |
- raw=$(git branch -r --contains ${{ github.ref }})
- branch=${raw/origin\/}
- echo ::set-output\ name=BASE::$branch
- echo "::debug::BASE is being set to $branch"
- - name: get-release-info
- id: get-release-info
- uses: pschlarb/indy-shared-gha/.github/actions/get-release-info@parametrization
- with:
- versionString: "${{ github.ref }}"
- - name: setPRBranch
- id: setPRBranch
- run: |
- if [[ "${{ steps.get-release-info.outputs.isRC }}" == "true" ]]; then
- echo ::set-output\ name=prBranch::update-plenum-rc-version
- else
- echo ::set-output\ name=prBranch::update-plenum-version
- fi
- # - name: Set up Python
- # uses: actions/setup-python@v2
- # with:
- # python-version: '3.8'
- # - name: Get New Node Version
- # id: nodeVersion
- # run: |
- # major=$(python3 -c "from indy_node import load_version; patch = load_version().parts[0]; print('' if patch is None else patch)")
- # minor=$(python3 -c "from indy_node import load_version; patch = load_version().parts[1]; print('' if patch is None else patch)")
- # patch=$(python3 -c "from indy_node import load_version; patch = load_version().parts[2]; patch+=1; print('' if patch is None else patch)")
- # if [[ "${{ inputs.isRC }}" == "true" ]]; then
- # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}rc1
- # else
- # echo ::set-output\ name=nodeVersion::${major}.${minor}.${patch}
- # fi
- - name: Get new Node Version
- id: nodeVersion
- uses: ./.github/actions/getNewNodeVersion
- with:
- isRC: ${{ steps.get-release-info.outputs.isRC }}
-
- updateAndCommit:
- runs-on: ubuntu-latest
- needs: taginfos
- steps:
- - name: checkout source code
- uses: actions/checkout@v3
- with:
- token: ${{ secrets.BOT_PR_PAT }}
- - name: Update Setup.py
- run: |
- sed -E -i 's/indy-plenum==[[:digit:]]+.[[:digit:]]+.[[:digit:]]+(.(dev|rc)[[:digit:]]+)?/indy-plenum==${{needs.taginfos.outputs.version}}/g' setup.py
- - name: CommitAndTag
- uses: EndBug/add-and-commit@v9
- with:
- author_name: ${{ github.actor }}
- author_email: ${{ github.event.pusher.email }}
- commit: --signoff
- message: 'Update Plenum Dependency to ${{needs.taginfos.outputs.version}}'
- push: "origin ${{ needs.taginfos.outputs.Branch}} --set-upstream --force"
- new_branch: ${{ needs.taginfos.outputs.Branch}}
- tag: "setRelease-v${{needs.taginfos.outputs.nodeVersion}}"
\ No newline at end of file
diff --git a/docs/source/release-workflow.png b/docs/source/release-workflow.png
new file mode 100644
index 0000000000000000000000000000000000000000..352718881bdcbbcb5bde094c30751b38c4e72d09
GIT binary patch
literal 146883
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