diff --git a/.github/workflows/frontend-build-and-publish-apps.yml b/.github/workflows/frontend-build-and-publish-apps.yml new file mode 100644 index 00000000..0a2cdea2 --- /dev/null +++ b/.github/workflows/frontend-build-and-publish-apps.yml @@ -0,0 +1,196 @@ +name: Frontend Build and Publish Apps +on: + workflow_call: + inputs: + node-version: + description: Node version to use (defaults to 14) + required: false + type: string + default: '14' + npm-registry-url: + description: The url address for npm registry (defaults to https://www.myget.org/F/river-tech/npm/) + required: false + type: string + default: https://www.myget.org/F/river-tech/npm/ + npm-registry-scope: + description: The name of the npm scope (defaults to @odin) + required: false + type: string + default: '@odin' + aws-region: + description: Which AWS region to use for publish storybook (defaults to eu-west-1) + required: false + type: string + default: eu-west-1 + dotnet-version: + description: dotnet version to use (defaults to 6.0.x) + required: false + type: string + default: '6.0.x' + secrets: + npm-token: + required: true + aws-access-key-id: + required: true + aws-secret-access-key: + required: true + github-token: + required: true +jobs: + build: + name: Build and publish + runs-on: ubuntu-latest + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_CLI_TELEMETRY_OPTOUT: "1" + PUBLISH_PATH: obj/Docker/publish + ODIN_CI_DEBUG_MODE: "true" + steps: + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ inputs.node-version }} + always-auth: true + registry-url: ${{ inputs.npm-registry-url }} + scope: ${{ inputs.npm-registry-scope }} + + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v2.0.0 + with: + dotnet-version: ${{ inputs.dotnet-version }} + + - name: Print environment versions + run: | + NODE_V=$(node --version) + NPM_V=$(npm -v) + echo node version':' $NODE_V + echo npm version':' $NPM_V + docker -v + docker-compose -v + DOTNET_CLI_V=$(dotnet --version) + echo dotnet cli version':' $DOTNET_CLI_V + git --version + + - name: Checkout + uses: actions/checkout@v3.0.0 + + - name: Install npm + run: npm ci + env: + NODE_AUTH_TOKEN: ${{ secrets.npm-token }} + + - name: Lint + run: npm run lint + + - name: Build + run: npm run build:rel + + - name: Install tools + run: npm i -g @odin/infra.ci@0.1.22 + env: + NODE_AUTH_TOKEN: ${{ secrets.npm-token }} + + - name: Dotnet restore/publish + run: | + SOLUTION=$(node -p "require('./package.json').vsBuildSolution") + dotnet restore $SOLUTION /p:Configuration=Release + dotnet publish $SOLUTION -c Release -o ./$PUBLISH_PATH + + - name: Set environment variables + run: | + PACKAGE_VERSION=$(node -p "require('./package.json').version") + echo "APP_NAME=$(node -p "require('./package.json').name")" >> $GITHUB_ENV + echo "GIT_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV + + if [[ "$GITHUB_REF_NAME" =~ ^feature\/(.*)$ ]] + then + echo "APP_VERSION=$PACKAGE_VERSION-demo-${BASH_REMATCH[1]}-$GITHUB_RUN_ID" >> $GITHUB_ENV + elif [[ "$GITHUB_REF_NAME" =~ ^hotfix\/(.*)$ ]] + then + echo "APP_VERSION=$PACKAGE_VERSION-hotfix-${BASH_REMATCH[1]}-$GITHUB_RUN_ID" >> $GITHUB_ENV + else + echo "APP_VERSION=$(ci get:app-version --packageVersion=$PACKAGE_VERSION --branch=$GITHUB_REF_NAME --incrementalSuffix=$GITHUB_RUN_ID)" >> $GITHUB_ENV + fi + + - name: Check if tag exists + uses: mukunku/tag-exists-action@v1.0.0 + id: tag + with: + tag: ${{ env.APP_VERSION }} + env: + GITHUB_TOKEN: ${{ secrets.github-token }} + + - name: Inform if tag exists + if: ${{ steps.tag.outputs.exists == 'true' }} + run: echo "::notice ::Tag already exists." + + - name: Configure AWS credentials + if: ${{ steps.tag.outputs.exists == 'false' }} + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.aws-access-key-id }} + aws-secret-access-key: ${{ secrets.aws-secret-access-key }} + aws-region: ${{ inputs.aws-region }} + + - name: Login to Amazon ECR + id: login-ecr + if: ${{ steps.tag.outputs.exists == 'false' }} + uses: aws-actions/amazon-ecr-login@v1 + + - name: Deploy + if: ${{ steps.tag.outputs.exists == 'false' }} + env: + ECR_HOST: ${{ steps.login-ecr.outputs.registry }} + run: | + docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.ci.yml build + docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.ci.yml push + + - name: Logout of Amazon ECR + if: ${{ steps.tag.outputs.exists == 'false' }} + run: docker logout ${{ steps.login-ecr.outputs.registry }} + + - name: Create Git tag for release + if: ${{ steps.tag.outputs.exists == 'false' }} + run: | + git tag $APP_VERSION + git push --tags + + - name: Downmerge master to develop + run: | + if [ "$GITHUB_REF_NAME" != "master" ] + then + echo "::notice ::Skipping downmerge. Branch is not master." + exit 0 + fi + + git fetch + git checkout develop + git config user.email "deploy-bot@riverigaming.com" + git config user.name "rig-autobot" + + if git merge --no-commit --no-ff --no-edit origin/master + then + if [ -z "$(git status --porcelain)" ] + then + echo "::notice ::Nothing to commit" + else + git commit --no-edit + git push origin develop + fi + else + if git merge HEAD + then + echo "::notice ::"Nothing to merge" + else + echo "::warning ::"Failed to downmerge. Conflicts between master and develop." + git merge --abort + fi + fi + + - name: Store npm artifact + uses: actions/upload-artifact@v3 + if: failure() + with: + name: npm-logs + path: ~/.npm/_logs/* + retention-days: 2 diff --git a/.github/workflows/frontend-build-and-publish-libs.yml b/.github/workflows/frontend-build-and-publish-libs.yml new file mode 100644 index 00000000..492b163f --- /dev/null +++ b/.github/workflows/frontend-build-and-publish-libs.yml @@ -0,0 +1,180 @@ +name: Frontend Build and Publish Library +on: + workflow_call: + inputs: + node-version: + description: Node version to use (defaults to 14) + required: false + type: string + default: '14' + npm-registry-url: + description: The url address for npm registry (defaults to https://www.myget.org/F/river-tech/npm/) + required: false + type: string + default: https://www.myget.org/F/river-tech/npm/ + npm-registry-scope: + description: The name of the npm scope (defaults to @odin) + required: false + type: string + default: '@odin' + junit-report-path: + description: The path to unit test report (defaults to ./junit/) + required: false + type: string + default: ./junit/ + junit-report-name: + description: The file name for unit test report (defaults to test-results.xml) + required: false + type: string + default: test-results.xml + aws-region: + description: Which AWS region to use for publish storybook (defaults to eu-west-1) + required: false + type: string + default: eu-west-1 + has-storybook: + description: Whether storybook exists in project (defaults to false) + required: false + type: boolean + default: false + secrets: + npm-token: + required: true + aws-access-key-id: + required: true + aws-secret-access-key: + required: true + github-token: + required: true +jobs: + build: + name: Build and publish library + runs-on: ubuntu-latest + steps: + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ inputs.node-version }} + always-auth: true + registry-url: ${{ inputs.npm-registry-url }} + scope: ${{ inputs.npm-registry-scope }} + + - name: Print environment versions + run: | + NODE_V=$(node --version) + NPM_V=$(npm -v) + echo node version':' $NODE_V + echo npm version':' $NPM_V + + - name: Checkout + uses: actions/checkout@v3.0.0 + + - name: Install npm + run: npm ci + env: + NODE_AUTH_TOKEN: ${{ secrets.npm-token }} + + - name: Build + run: npm run build + + - name: Test + run: npm run test -- --browsers=ChromeHeadlessCI --no-watch --no-progress + + - name: Build storybook + if: inputs.has-storybook + run: npm run build:storybook + + - name: Check if commit is publishable + id: commit + run: | + if git log --format=%B -n 1 | egrep "^(style|test|docs)"; then + echo "::set-output name=publishable::false" + echo "::notice ::This update doesn't need to be published." + else + echo "::set-output name=publishable::true" + fi + + - name: Fetch tag from lerna + id: lerna + if: ${{ steps.commit.outputs.publishable == 'true' }} + run: | + TAG=$(node -p "require('./lerna.json').version") + echo "::set-output name=tag::${TAG}" + + - name: Check if tag exists + uses: mukunku/tag-exists-action@v1.0.0 + id: tag + with: + tag: ${{ steps.lerna.outputs.tag }} + env: + GITHUB_TOKEN: ${{ secrets.github-token }} + + - name: Inform if tag exists + if: ${{ steps.tag.outputs.exists == 'true' }} + run: echo "::notice ::Tag already exists. Please make sure you bump version!" + + - name: Configure AWS credentials + if: ${{ inputs.has-storybook && steps.commit.outputs.publishable == 'true' && steps.tag.outputs.exists == 'false' }} + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.aws-access-key-id }} + aws-secret-access-key: ${{ secrets.aws-secret-access-key }} + aws-region: ${{ inputs.aws-region }} + + - name: Login to Amazon ECR + id: login-ecr + if: ${{ inputs.has-storybook && steps.commit.outputs.publishable == 'true' && steps.tag.outputs.exists == 'false' }} + uses: aws-actions/amazon-ecr-login@v1 + + - name: Publish storybook + if: ${{ inputs.has-storybook && steps.commit.outputs.publishable == 'true' && steps.tag.outputs.exists == 'false' }} + env: + ECR_HOST: ${{ steps.login-ecr.outputs.registry }} + run: | + TAG=$(node -p "require('./storybook/package.json').version") + if $GITHUB_REF_NAME == 'develop' + then + TAG=$TAG-dev-$GITHUB_RUN_ID + elif [[ $GITHUB_REF_NAME =~ ^feature\/(.*)$ ]] + then + TAG=$TAG-demo-${BASH_REMATCH[1]}-$GITHUB_RUN_ID + fi + + [[ $ECR_HOST =~ ^([0-9]*) ]] && REGISTRY=${BASH_REMATCH[1]} + + if aws ecr describe-images --repository-name=odin.ngx-storybook --registry-id $REGISTRY --image-ids=imageTag=$TAG > /dev/null 2>&1; then + echo "::notice ::$TAG already exists on remote... skipping..." + exit 0 + fi + + TAG=$TAG docker-compose build + TAG=$TAG docker-compose push + + - name: Logout of Amazon ECR + if: ${{ inputs.has-storybook && steps.commit.outputs.publishable == 'true' && steps.tag.outputs.exists == 'false' }} + run: docker logout ${{ steps.login-ecr.outputs.registry }} + + - name: Deploy + if: ${{ steps.commit.outputs.publishable == 'true' && steps.tag.outputs.exists == 'false' }} + run: | + echo "git tag" + PACKAGE_VERSION=$(node -p "require('./lerna.json').version") + git tag $PACKAGE_VERSION + git push --tags + npm run publish:rel + + - name: Store tests artifact + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ inputs.junit-report-name }} + path: ${{ inputs.junit-report-path }} + retention-days: 2 + + - name: Store npm artifact + uses: actions/upload-artifact@v3 + if: failure() + with: + name: npm-logs + path: ~/.npm/_logs/* + retention-days: 2 diff --git a/.github/workflows/frontend-build-and-tag-configs.yml b/.github/workflows/frontend-build-and-tag-configs.yml new file mode 100644 index 00000000..dd5df1fd --- /dev/null +++ b/.github/workflows/frontend-build-and-tag-configs.yml @@ -0,0 +1,72 @@ +name: Frontend Build and Tag Configs +on: + workflow_call: + inputs: + aws-region: + description: Which AWS region to use for publish storybook (defaults to eu-west-1) + required: false + type: string + default: eu-west-1 + secrets: + aws-access-key-id: + required: true + aws-secret-access-key: + required: true +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.aws-access-key-id }} + aws-secret-access-key: ${{ secrets.aws-secret-access-key }} + aws-region: ${{ inputs.aws-region }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Checkout + uses: actions/checkout@v3.0.0 + + - name: Print environment versions + uses: mosteo-actions/docker-run@v1 + with: + image: ${{ steps.login-ecr.outputs.registry }}/deploy-ci:7.3.40 + command: ci deps + + - name: Lint JSON + uses: mosteo-actions/docker-run@v1 + with: + image: ${{ steps.login-ecr.outputs.registry }}/deploy-ci:7.3.40 + command: ci lint-json "./config/**/*.json" + + - name: Logout of Amazon ECR + run: docker logout ${{ steps.login-ecr.outputs.registry }} + + tag: + name: Tag + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3.0.0 + + - name: Check if branch is publishable + id: branch + run: | + if ! ([[ $GITHUB_REF_NAME =~ ^([0-9].*)\.x$ ]]); then + echo "::set-output name=publishable::false" + echo "::notice ::Non-publishable branch." + else + echo "::set-output name=publishable::true" + fi + + - name: Git Tag + if: ${{ steps.branch.outputs.publishable == 'true' }} + run: | + PACKAGE_VERSION=$(node -p "require('./package.json').version") + git tag $PACKAGE_VERSION + git push --tags