mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-32905 Rework pr pipeline (#11853)
* [AAE-32905] - Improve ADF workflow * [ci:force] * [AAE-32905] - Improve cache use * [AAE-32905] - Improve cache use * [AAE-32905] - Improved workflows * [AAE-32905] - Checking cache * [AAE-32905] - Checking cache * [AAE-32905] - Fix cli * [AAE-32905] - Fix cache * [AAE-32905] - Fix cache * [AAE-32905] - Fix cache * [AAE-32905] - improving workflow and adding some storybook tests * [AAE-32905] - improving workflow and adding some storybook tests * [AAE-32905] - Added more improvements * [AAE-32905] - Added more improvements * [AAE-32905] - bugfix * [AAE-32905] - Added missing part to the cache * [AAE-32905] - bugfix * [AAE-32905] - fixed cache poisoning * [AAE-32905] - timing jobs * [AAE-32905] - chosen to build all together as it's more efficient * [AAE-32905] - Fixed script injection issue
This commit is contained in:
+2
-2
@@ -10,9 +10,9 @@
|
|||||||
# precedence. When someone opens a pull request that only
|
# precedence. When someone opens a pull request that only
|
||||||
# modifies JS files, only @js-owner and not the global
|
# modifies JS files, only @js-owner and not the global
|
||||||
# owner(s) will be requested for a review.
|
# owner(s) will be requested for a review.
|
||||||
/e2e/ @eromano @cristinaj
|
/e2e/ @eromano
|
||||||
|
|
||||||
# The `docs/*` pattern will match files like
|
# The `docs/*` pattern will match files like
|
||||||
# `docs/getting-started.md` but not further nested files like
|
# `docs/getting-started.md` but not further nested files like
|
||||||
# `docs/build-app/troubleshooting.md`.
|
# `docs/build-app/troubleshooting.md`.
|
||||||
/docs/ @m-hulbert @eromano
|
/docs/ @eromano
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
name: 'Save Nx Cache'
|
||||||
|
description: 'Save Nx cache and dist outputs only when the job succeeds'
|
||||||
|
inputs:
|
||||||
|
cache-suffix:
|
||||||
|
description: 'Must match the cache-suffix used in the setup action'
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Save nx cache
|
||||||
|
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
nxcache
|
||||||
|
.nx
|
||||||
|
dist
|
||||||
|
key: ${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-${{ github.sha }}
|
||||||
@@ -6,6 +6,15 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
default: 'true'
|
default: 'true'
|
||||||
|
cache-suffix:
|
||||||
|
description: 'Suffix to make Nx cache key unique per job (e.g. matrix project name)'
|
||||||
|
required: false
|
||||||
|
default: 'default'
|
||||||
|
full-setup:
|
||||||
|
description: 'Run git-latest-tag, npm-tag, and before-install (requires fetch-depth: 0). Set to false for matrix jobs that only need node/cache.'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: 'true'
|
||||||
act:
|
act:
|
||||||
description: 'enable act debug'
|
description: 'enable act debug'
|
||||||
required: false
|
required: false
|
||||||
@@ -15,36 +24,50 @@ outputs:
|
|||||||
npm-tag:
|
npm-tag:
|
||||||
description: 'NPM tag'
|
description: 'NPM tag'
|
||||||
value: ${{ steps.set-npm-tag.outputs.npm-tag }}
|
value: ${{ steps.set-npm-tag.outputs.npm-tag }}
|
||||||
|
node-modules-cache-hit:
|
||||||
|
description: 'Whether node_modules cache was hit'
|
||||||
|
value: ${{ steps.node-modules-cache.outputs.cache-hit }}
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
|
- name: Set consistent machine ID for Nx cache
|
||||||
|
shell: bash
|
||||||
|
run: echo "nx-github-actions" | sudo tee /etc/machine-id > /dev/null
|
||||||
- name: install NPM
|
- name: install NPM
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache-dependency-path: package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- name: get latest tag sha
|
- name: get latest tag sha
|
||||||
|
if: ${{ inputs.full-setup == 'true' }}
|
||||||
id: tag-sha
|
id: tag-sha
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@f95467b62527ce087c9a1b7e55c467061cf827a0 # v17.6.1
|
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@8d76614b374e521d792b4a1c9827409960b66bae # v17.6.0
|
||||||
# CACHE
|
- name: load "NPM TAG"
|
||||||
- name: Node Modules cache
|
if: ${{ inputs.full-setup == 'true' }}
|
||||||
|
id: set-npm-tag
|
||||||
|
uses: ./.github/actions/set-npm-tag
|
||||||
|
- name: Cache node modules
|
||||||
id: node-modules-cache
|
id: node-modules-cache
|
||||||
if: ${{ inputs.enable-node-modules-cache == 'true' }}
|
if: ${{ inputs.enable-node-modules-cache == 'true' }}
|
||||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||||
env:
|
with:
|
||||||
cache-name: node-modules-cache
|
path: node_modules
|
||||||
|
key: ${{ runner.os }}-node-modules-${{ hashFiles('.nvmrc') }}-${{ hashFiles('package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-modules-${{ hashFiles('.nvmrc') }}-
|
||||||
|
- name: Restore nx cache
|
||||||
|
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
node_modules
|
nxcache
|
||||||
key: .npm-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
.nx
|
||||||
|
dist
|
||||||
|
key: ${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
.npm-${{ runner.os }}-build-${{ env.cache-name }}-
|
${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-${{ hashFiles('nx.json') }}-
|
||||||
.npm-${{ runner.os }}-build-
|
${{ runner.os }}-nxcache-${{ inputs.cache-suffix }}-
|
||||||
.npm-${{ runner.os }}-
|
|
||||||
- name: load "NPM TAG"
|
|
||||||
id: set-npm-tag
|
|
||||||
uses: ./.github/actions/set-npm-tag
|
|
||||||
- name: before install script
|
- name: before install script
|
||||||
|
if: ${{ inputs.full-setup == 'true' }}
|
||||||
uses: ./.github/actions/before-install
|
uses: ./.github/actions/before-install
|
||||||
with:
|
with:
|
||||||
act: ${{ inputs.act }}
|
act: ${{ inputs.act }}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
name: "Build Lib Workflow"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
base_ref:
|
||||||
|
description: 'Base branch for affected calculation'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: 'develop'
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: "--max-old-space-size=5120"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: "Build affected libs"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Setup environment
|
||||||
|
id: setup-env
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
with:
|
||||||
|
cache-suffix: build
|
||||||
|
full-setup: 'false'
|
||||||
|
- name: Install dependencies
|
||||||
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
|
run: npm ci
|
||||||
|
- name: Build affected libs
|
||||||
|
env:
|
||||||
|
BASE_REF: ${{ inputs.base_ref }}
|
||||||
|
run: npx nx affected --target=build --base=origin/$BASE_REF --head=HEAD --configuration=production --exclude=stories
|
||||||
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: ./.github/actions/save-nx-cache
|
||||||
|
with:
|
||||||
|
cache-suffix: build
|
||||||
+214
-186
@@ -31,16 +31,14 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BASE_REF: ${{ github.base_ref }}
|
|
||||||
HEAD_REF: ${{ github.head_ref }}
|
|
||||||
GH_COMMIT: ${{ github.sha }}
|
GH_COMMIT: ${{ github.sha }}
|
||||||
GH_BUILD_NUMBER: ${{ github.run_id }}
|
|
||||||
LOG_LEVEL: "ERROR"
|
|
||||||
NODE_OPTIONS: "--max-old-space-size=5120"
|
NODE_OPTIONS: "--max-old-space-size=5120"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-checks:
|
pre-checks:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
code-changed: ${{ steps.path-filter.outputs.code-changed }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
@@ -57,150 +55,121 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Detect code changes
|
||||||
|
id: path-filter
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||||
|
echo "Not a PR event — assuming code changed"
|
||||||
|
echo "code-changed=true" >> $GITHUB_OUTPUT
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILES=$(gh api /repos/$GITHUB_REPOSITORY/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[].filename')
|
||||||
|
|
||||||
|
CODE_CHANGED="false"
|
||||||
|
while IFS= read -r file; do
|
||||||
|
case "$file" in
|
||||||
|
*.md|docs/*|.github/*.md|.github/CODEOWNERS|.github/dependabot.yml|LICENSE*|NOTICE*|.editorconfig|.gitattributes)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
CODE_CHANGED="true"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$FILES"
|
||||||
|
|
||||||
|
echo "code-changed=$CODE_CHANGED" >> $GITHUB_OUTPUT
|
||||||
|
echo "Code changed: $CODE_CHANGED"
|
||||||
|
|
||||||
check-if-pr-is-approved:
|
check-if-pr-is-approved:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check if PR approval can be skipped
|
||||||
|
id: skip-check
|
||||||
|
env:
|
||||||
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
DEVEL_FLAG: ${{ inputs.devel }}
|
||||||
|
COMMIT_MESSAGE: ${{ github.event.head_commit.message || github.event.pull_request.title || '' }}
|
||||||
|
run: |
|
||||||
|
skip="false"
|
||||||
|
|
||||||
|
if [ "$EVENT_NAME" == "schedule" ] || [ "$EVENT_NAME" == "workflow_dispatch" ]; then
|
||||||
|
echo -e "\033[32mSchedule/dispatch event — skipping approval check\033[0m"
|
||||||
|
skip="true"
|
||||||
|
elif [ "$ACTOR" == "dependabot[bot]" ] || [ "$ACTOR" == "alfresco-build" ]; then
|
||||||
|
echo -e "\033[32mCommit by $ACTOR — skipping approval check\033[0m"
|
||||||
|
skip="true"
|
||||||
|
elif [[ "$COMMIT_MESSAGE" == *"[ci:force]"* ]]; then
|
||||||
|
echo -e "\033[32m[ci:force] flag detected — skipping approval check\033[0m"
|
||||||
|
skip="true"
|
||||||
|
elif [[ "$DEVEL_FLAG" == "true" ]]; then
|
||||||
|
echo -e "\033[32mDevel flag — skipping approval check\033[0m"
|
||||||
|
skip="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "skip=$skip" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Get PR number
|
||||||
|
if: ${{ steps.skip-check.outputs.skip != 'true' }}
|
||||||
|
id: pr-number
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
PR_NUMBER="${{ github.event.pull_request.number }}"
|
||||||
|
if [ -z "$PR_NUMBER" ]; then
|
||||||
|
PR_NUMBER=$(gh pr view --json number --jq '.number' 2>/dev/null || echo "")
|
||||||
|
fi
|
||||||
|
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||||
|
echo "PR: $PR_NUMBER"
|
||||||
|
|
||||||
|
- name: Check if PR is approved
|
||||||
|
if: ${{ steps.skip-check.outputs.skip != 'true' && steps.pr-number.outputs.pr_number != '' }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
|
||||||
|
run: |
|
||||||
|
echo "Checking approval for PR: $PR_NUMBER"
|
||||||
|
checkApproval=$(gh api /repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews | jq '.[] | select(.state == "APPROVED") | .user.login')
|
||||||
|
if [[ $checkApproval ]]; then
|
||||||
|
echo -e "\033[32mPR approved\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[31mPR NOT approved\033[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
setup:
|
||||||
|
timeout-minutes: 30
|
||||||
|
name: "Setup"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check-if-pr-is-approved, pre-checks]
|
||||||
|
if: ${{ needs.pre-checks.outputs.code-changed == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- name: Setup environment
|
||||||
- name: Get branch name
|
id: setup-env
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@f95467b62527ce087c9a1b7e55c467061cf827a0 # v17.6.1
|
uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Save commit message
|
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@f95467b62527ce087c9a1b7e55c467061cf827a0 # v17.6.1
|
|
||||||
with:
|
with:
|
||||||
header-only: true
|
cache-suffix: setup
|
||||||
|
- name: Install dependencies
|
||||||
- name: ci:force flag parser
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
shell: bash
|
run: npm ci
|
||||||
env:
|
- name: Bundle
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
|
||||||
ACTOR: ${{ github.actor }}
|
|
||||||
run: |
|
run: |
|
||||||
if [ "$EVENT_NAME" == "schedule" ] || [ "$ACTOR" == "dependabot[bot]" ]; then
|
|
||||||
echo -e "\033[32mci:force check can be skipped\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
elif [[ "$COMMIT_MESSAGE" == *"[ci:force]"* ]]; then
|
|
||||||
echo -e "\033[32m[ci:force] flag detected. No need for approval.\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Get PR number
|
|
||||||
if: ${{ github.event_name != 'schedule' && github.event_name != 'workflow_dispatch' }}
|
|
||||||
uses: kamatama41/get-pr-number-action@ff143e03abaa79d346ca5407d49d335b5def979e # v1.0.1
|
|
||||||
id: action
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: show pr number
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ steps.action.outputs.number }}
|
|
||||||
run: |
|
|
||||||
echo "PR: $PR_NUMBER"
|
|
||||||
|
|
||||||
- name: check if pr is approved
|
|
||||||
env:
|
|
||||||
DEVEL_FLAG: ${{ inputs.devel }}
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
skip_check: "false"
|
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
|
||||||
ACTOR: ${{ github.actor }}
|
|
||||||
PR_NUMBER: ${{ steps.action.outputs.number }}
|
|
||||||
run: |
|
|
||||||
if [ "$EVENT_NAME" == "schedule" ] || [ "$ACTOR" == "dependabot[bot]" ]; then
|
|
||||||
echo -e "\033[32mci:force check can be skipped\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
elif [[ "$COMMIT_MESSAGE" == *"[ci:force]"* ]]; then
|
|
||||||
echo -e "\033[32m[ci:force] flag detected. No need for approval.\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ACTOR" == "dependabot[bot]" ] || [ "$ACTOR" == "alfresco-build" ]; then
|
|
||||||
echo -e "\033[32mCommit by $ACTOR. No need for approval.\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
fi
|
|
||||||
if [ "$EVENT_NAME" == "schedule" ] || [ "$EVENT_NAME" == "workflow_dispatch" ]; then
|
|
||||||
echo -e "\033[32mSchedule event\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$DEVEL_FLAG" == "true" ]]; then
|
|
||||||
echo -e "\033[32mDevel flag\033[0m"
|
|
||||||
skip_check="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$skip_check" == "false" ]; then
|
|
||||||
echo "Checking PR approval"
|
|
||||||
prNumber=$PR_NUMBER
|
|
||||||
echo "PR: $prNumber"
|
|
||||||
checkApproval=$(gh api /repos/$GITHUB_REPOSITORY/pulls/$prNumber/reviews | jq '.[] | select(.state == "APPROVED") | .user.login')
|
|
||||||
if [[ $checkApproval ]]; then
|
|
||||||
echo -e "\033[32mPR approved\033[0m"
|
|
||||||
else
|
|
||||||
echo -e "\033[31mPR NOT approved\033[0m"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
setup:
|
|
||||||
# long timeout required when cache has to be recreated
|
|
||||||
timeout-minutes: 30
|
|
||||||
name: "Setup"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [check-if-pr-is-approved, pre-checks]
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Fetch all history for all tags and branches
|
|
||||||
- uses: ./.github/actions/setup
|
|
||||||
- name: install
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run bundle:js-api
|
npm run bundle:js-api
|
||||||
npm run bundle:cli
|
npm run bundle:cli
|
||||||
- uses: ./.github/actions/upload-node-modules-and-artifacts
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
unit-tests:
|
uses: ./.github/actions/save-nx-cache
|
||||||
timeout-minutes: 30
|
|
||||||
name: "Unit tests: ${{ matrix.unit-tests.name }}"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [setup]
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
# max-parallel: 4
|
|
||||||
matrix:
|
|
||||||
unit-tests:
|
|
||||||
- name: js-api
|
|
||||||
exclude: "core,insights,content-services,process-services,process-services-cloud,eslint-plugin-eslint-angular"
|
|
||||||
- name: content-services
|
|
||||||
exclude: "insights,core,extensions,process-services,process-services-cloud,eslint-plugin-eslint-angular,js-api"
|
|
||||||
- name: core
|
|
||||||
exclude: "insights,content-services,process-services,process-services-cloud,eslint-plugin-eslint-angular,js-api"
|
|
||||||
- name: insights
|
|
||||||
exclude: "core,extensions,content-services,process-services-cloud,process-services,eslint-plugin-eslint-angular,js-api"
|
|
||||||
- name: process-services
|
|
||||||
exclude: "core,extensions,content-services,process-services-cloud,insights,eslint-plugin-eslint-angular,js-api"
|
|
||||||
- name: process-services-cloud
|
|
||||||
exclude: "insights,core,extensions,content-services,process-services$,eslint-plugin-eslint-angular,js-api"
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch all history for all tags and branches
|
cache-suffix: setup
|
||||||
- uses: ./.github/actions/setup
|
|
||||||
- uses: ./.github/actions/download-node-modules-and-artifacts
|
|
||||||
- name: Run unit tests
|
|
||||||
env:
|
|
||||||
EXCLUDE_PATTERN: ${{ matrix.unit-tests.exclude }}
|
|
||||||
run: |
|
|
||||||
/usr/bin/xvfb-run --auto-servernum npm run test:affected -- $NX_CALCULATION_FLAGS --exclude=$EXCLUDE_PATTERN
|
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
# long timeout required when cache has to be recreated
|
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
name: "Lint"
|
name: "Lint"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -209,71 +178,133 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch all history for all tags and branches
|
fetch-depth: 0
|
||||||
- uses: ./.github/actions/setup
|
- name: Setup environment
|
||||||
- uses: ./.github/actions/download-node-modules-and-artifacts
|
id: setup-env
|
||||||
- run: npm run lint:affected -- $NX_CALCULATION_FLAGS
|
uses: ./.github/actions/setup
|
||||||
|
|
||||||
build-libs:
|
|
||||||
# long timeout required when cache has to be recreated
|
|
||||||
timeout-minutes: 30
|
|
||||||
name: "Build libs"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [setup]
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch all history for all tags and branches
|
cache-suffix: lint
|
||||||
- uses: ./.github/actions/setup
|
full-setup: 'false'
|
||||||
- uses: ./.github/actions/download-node-modules-and-artifacts
|
- name: Install dependencies
|
||||||
- run: NX_REJECT_UNKNOWN_LOCAL_CACHE=0 npm run build:affected -- $NX_CALCULATION_FLAGS --prod
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
- uses: ./.github/actions/upload-node-modules-and-artifacts
|
run: npm ci
|
||||||
|
- name: Run lint
|
||||||
|
env:
|
||||||
|
BASE_REF: ${{ github.base_ref || 'develop' }}
|
||||||
|
run: npx nx affected --target=lint --base=origin/$BASE_REF --head=HEAD
|
||||||
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: ./.github/actions/save-nx-cache
|
||||||
|
with:
|
||||||
|
cache-suffix: lint
|
||||||
|
|
||||||
|
trigger-build:
|
||||||
|
name: "Build Libs"
|
||||||
|
needs: [setup]
|
||||||
|
uses: ./.github/workflows/build-lib-workflow.yml
|
||||||
|
with:
|
||||||
|
base_ref: ${{ github.base_ref || 'develop' }}
|
||||||
|
|
||||||
build-storybook:
|
build-storybook:
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
name: "Build storybook"
|
name: "Build Storybook"
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [setup]
|
needs: [setup]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch all history for all tags and branches
|
fetch-depth: 0
|
||||||
- uses: ./.github/actions/setup
|
- name: Setup environment
|
||||||
- uses: ./.github/actions/download-node-modules-and-artifacts
|
id: setup-env
|
||||||
- run: npm run build-storybook
|
uses: ./.github/actions/setup
|
||||||
- uses: ./.github/actions/upload-node-modules-and-artifacts
|
with:
|
||||||
|
cache-suffix: storybook
|
||||||
|
full-setup: 'false'
|
||||||
|
- name: Install dependencies
|
||||||
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
|
run: npm ci
|
||||||
|
- name: Build Storybook
|
||||||
|
env:
|
||||||
|
BASE_REF: ${{ github.base_ref || 'develop' }}
|
||||||
|
run: |
|
||||||
|
npx nx affected --target=build-storybook --base=origin/$BASE_REF --head=HEAD --configuration=ci
|
||||||
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: ./.github/actions/save-nx-cache
|
||||||
|
with:
|
||||||
|
cache-suffix: storybook
|
||||||
|
|
||||||
|
trigger-unit-tests:
|
||||||
|
name: "Unit Tests"
|
||||||
|
needs: [setup]
|
||||||
|
uses: ./.github/workflows/unit-test-workflow.yml
|
||||||
|
with:
|
||||||
|
base_ref: ${{ github.base_ref || 'develop' }}
|
||||||
|
|
||||||
|
PR-size-check:
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check PR size
|
||||||
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { data: pr } = await github.rest.pulls.get({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
pull_number: context.issue.number,
|
||||||
|
});
|
||||||
|
|
||||||
|
const additions = pr.additions;
|
||||||
|
const deletions = pr.deletions;
|
||||||
|
const totalChanges = additions + deletions;
|
||||||
|
const changedFiles = pr.changed_files;
|
||||||
|
|
||||||
|
let size = 'S';
|
||||||
|
if (totalChanges > 1000 || changedFiles > 30) size = 'XL';
|
||||||
|
else if (totalChanges > 500 || changedFiles > 20) size = 'L';
|
||||||
|
else if (totalChanges > 200 || changedFiles > 10) size = 'M';
|
||||||
|
|
||||||
|
core.summary
|
||||||
|
.addHeading('PR Size: ' + size, 3)
|
||||||
|
.addTable([
|
||||||
|
[{data: 'Metric', header: true}, {data: 'Count', header: true}],
|
||||||
|
['Files changed', String(changedFiles)],
|
||||||
|
['Additions', '+' + String(additions)],
|
||||||
|
['Deletions', '-' + String(deletions)],
|
||||||
|
['Total changes', String(totalChanges)],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (size === 'XL') {
|
||||||
|
core.summary.addRaw('⚠️ This PR is very large. Consider splitting it into smaller PRs for easier review.');
|
||||||
|
}
|
||||||
|
|
||||||
|
await core.summary.write();
|
||||||
|
|
||||||
|
if (size === 'XL') {
|
||||||
|
core.warning('This PR has ' + totalChanges + ' changes across ' + changedFiles + ' files. Consider splitting it for easier review.');
|
||||||
|
}
|
||||||
|
|
||||||
PR-forbidden-labels:
|
PR-forbidden-labels:
|
||||||
if: ${{ inputs.cron-run == '' || inputs.cron-run == 'false' }}
|
if: ${{ inputs.cron-run == '' || inputs.cron-run == 'false' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- id: checkoutRepo
|
- name: Check for forbidden labels
|
||||||
name: Checkout repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- name: PR contains forbidden labels
|
|
||||||
id: pr-forbidden
|
|
||||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const issueHasLabels = require('./scripts/github/update/check-issue-has-label.js');
|
const { data: issue } = await github.rest.issues.get({
|
||||||
const checkLabels = ['next version ➡️', 'do not merge🙅🏻♂️'];
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
});
|
||||||
|
const labels = issue.labels?.map(item => item.name) || [];
|
||||||
|
const forbidden = ['next version ➡️', 'do not merge🙅🏻♂️'];
|
||||||
|
|
||||||
const hasLabel = await issueHasLabels({github, context, checkLabels})
|
if (forbidden.some(l => labels.includes(l))) {
|
||||||
|
|
||||||
if(hasLabel) {
|
|
||||||
core.setFailed('The PR contains a forbidden label! You are not allowed to merge until the label is there.');
|
core.setFailed('The PR contains a forbidden label! You are not allowed to merge until the label is there.');
|
||||||
}
|
}
|
||||||
- name: Check value after
|
|
||||||
env:
|
|
||||||
STEP_RESULT: ${{ toJson(steps.pr-forbidden.*.result) }}
|
|
||||||
HAS_FAILURE: ${{ contains(toJson(steps.pr-forbidden.*.result), 'failure') }}
|
|
||||||
run: |
|
|
||||||
echo "Step result: $STEP_RESULT"
|
|
||||||
echo "Has failure: $HAS_FAILURE"
|
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
@@ -284,16 +315,13 @@ jobs:
|
|||||||
check-if-pr-is-approved,
|
check-if-pr-is-approved,
|
||||||
pre-checks,
|
pre-checks,
|
||||||
setup,
|
setup,
|
||||||
unit-tests,
|
trigger-unit-tests,
|
||||||
lint,
|
lint,
|
||||||
build-libs,
|
trigger-build,
|
||||||
build-storybook,
|
build-storybook,
|
||||||
|
PR-forbidden-labels,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Check job execution status
|
- name: Check job execution status
|
||||||
if: >-
|
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
|
||||||
${{
|
|
||||||
contains(needs.*.result, 'failure')
|
|
||||||
|| contains(needs.*.result, 'cancelled')
|
|
||||||
}}
|
|
||||||
run: exit 1
|
run: exit 1
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
name: "Unit Tests Workflow"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
base_ref:
|
||||||
|
description: 'Base branch for affected calculation'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: 'develop'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-affected-matrix:
|
||||||
|
name: "Generate affected matrix"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
unitMatrix: ${{ steps.set-matrix.outputs.unitMatrix }}
|
||||||
|
hasProjects: ${{ steps.set-matrix.outputs.hasProjects }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Setup environment
|
||||||
|
id: setup-env
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
with:
|
||||||
|
cache-suffix: test-matrix
|
||||||
|
- name: Install dependencies
|
||||||
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
|
run: npm ci
|
||||||
|
- name: Generate affected projects matrix
|
||||||
|
id: set-matrix
|
||||||
|
env:
|
||||||
|
BASE_REF: ${{ inputs.base_ref }}
|
||||||
|
run: |
|
||||||
|
echo "Base ref is $BASE_REF"
|
||||||
|
AFFECTED_UNIT=$(npx nx show projects --affected --target=test --base=origin/$BASE_REF --head=HEAD --select=projects --plain --exclude=cli,stories,eslint-angular)
|
||||||
|
echo "Affected projects for UNIT: $AFFECTED_UNIT"
|
||||||
|
|
||||||
|
if [ -z "$AFFECTED_UNIT" ]; then
|
||||||
|
echo "No affected projects found"
|
||||||
|
echo "hasProjects=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "unitMatrix=[]" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
UNIT_MATRIX_JSON=$(echo "$AFFECTED_UNIT" | xargs -n1 | jq -R -s -c 'split("\n") | map(select(length > 0)) | map({ "project": . })')
|
||||||
|
echo "Matrix UNIT: $UNIT_MATRIX_JSON"
|
||||||
|
echo "hasProjects=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "unitMatrix=$UNIT_MATRIX_JSON" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: ./.github/actions/save-nx-cache
|
||||||
|
with:
|
||||||
|
cache-suffix: test-matrix
|
||||||
|
|
||||||
|
unit-tests:
|
||||||
|
timeout-minutes: 30
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: generate-affected-matrix
|
||||||
|
if: ${{ needs.generate-affected-matrix.outputs.hasProjects == 'true' }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include: ${{ fromJson(needs.generate-affected-matrix.outputs.unitMatrix) }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
- name: Setup environment
|
||||||
|
id: setup-env
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
with:
|
||||||
|
cache-suffix: test-${{ matrix.project }}
|
||||||
|
full-setup: 'false'
|
||||||
|
- name: Install dependencies
|
||||||
|
if: ${{ steps.setup-env.outputs.node-modules-cache-hit != 'true' }}
|
||||||
|
run: npm ci
|
||||||
|
- name: Run unit tests for ${{ matrix.project }}
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: "--max-old-space-size=5120"
|
||||||
|
run: |
|
||||||
|
xvfb-run --auto-servernum npx nx run ${{ matrix.project }}:test
|
||||||
|
- name: Save nx cache
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: ./.github/actions/save-nx-cache
|
||||||
|
with:
|
||||||
|
cache-suffix: test-${{ matrix.project }}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# CI Commands and Labels
|
||||||
|
|
||||||
|
Reference for flags and labels that control CI behavior on pull requests.
|
||||||
|
|
||||||
|
## PR Title Flags
|
||||||
|
|
||||||
|
Include these flags anywhere in the **PR title** to modify CI behavior.
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
|------|--------|
|
||||||
|
| `[ci:force]` | Skips the PR approval check, allowing the full pipeline to run without an approved review. Useful for testing CI changes on draft PRs. |
|
||||||
|
|
||||||
|
Example: `[AAE-12345] Fix pagination component [ci:force]`
|
||||||
|
|
||||||
|
## Commit Message Flags
|
||||||
|
|
||||||
|
Include these flags in a **commit message** to modify how Nx calculates affected projects.
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
|------|--------|
|
||||||
|
| `[affected:*]` | Forces all Nx targets to run against all projects, ignoring the affected calculation. Equivalent to `--all`. |
|
||||||
|
|
||||||
|
## PR Labels
|
||||||
|
|
||||||
|
Labels applied to the PR that affect CI behavior.
|
||||||
|
|
||||||
|
| Label | Effect |
|
||||||
|
|-------|--------|
|
||||||
|
| `do not merge` | Blocks the PR from passing the finalize check. CI will fail until the label is removed. |
|
||||||
|
| `next version` | Same as above - blocks the PR from merging. Used to hold PRs for the next release cycle. |
|
||||||
|
| `hxp-upstream` | (Release only) Triggers the HxP upstream propagation workflow after a successful release. |
|
||||||
|
|
||||||
|
## Automatic Skip Conditions
|
||||||
|
|
||||||
|
The approval check is automatically skipped for:
|
||||||
|
|
||||||
|
- **Scheduled runs** (`schedule` event)
|
||||||
|
- **Workflow dispatch** (`workflow_dispatch` event)
|
||||||
|
- **Dependabot PRs** (actor is `dependabot[bot]`)
|
||||||
|
- **Build bot PRs** (actor is `alfresco-build`)
|
||||||
|
- **Devel flag** (when `devel: true` is passed via `workflow_call`)
|
||||||
|
|
||||||
|
## Path-Based Filtering
|
||||||
|
|
||||||
|
PRs that only modify non-code files skip the build, test, and lint jobs entirely. Files considered non-code:
|
||||||
|
|
||||||
|
- Markdown files (`*.md`)
|
||||||
|
- Documentation (`docs/`)
|
||||||
|
- `LICENSE`, `NOTICE`
|
||||||
|
- `.editorconfig`, `.gitattributes`
|
||||||
|
- `.github/CODEOWNERS`, `.github/dependabot.yml`
|
||||||
|
|
||||||
|
## PR Size Check
|
||||||
|
|
||||||
|
Every PR gets an automatic size classification displayed in the job summary:
|
||||||
|
|
||||||
|
| Size | Criteria |
|
||||||
|
|------|----------|
|
||||||
|
| **S** | < 200 total changes and < 10 files |
|
||||||
|
| **M** | 200-500 total changes or 10-20 files |
|
||||||
|
| **L** | 500-1000 total changes or 20-30 files |
|
||||||
|
| **XL** | > 1000 total changes or > 30 files (warning annotation added) |
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
"targets": {
|
"targets": {
|
||||||
"build": {
|
"build": {
|
||||||
"executor": "nx:run-commands",
|
"executor": "nx:run-commands",
|
||||||
|
"outputs": ["{workspaceRoot}/dist/libs/cli"],
|
||||||
"options": {
|
"options": {
|
||||||
"command": "cd lib/cli && npm run dist"
|
"command": "cd lib/cli && npm run dist"
|
||||||
},
|
},
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
},
|
},
|
||||||
"copyToNodeModules": {
|
"copyToNodeModules": {
|
||||||
"executor": "nx:run-commands",
|
"executor": "nx:run-commands",
|
||||||
|
"cache": false,
|
||||||
"options": {
|
"options": {
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
|
|||||||
+11
@@ -19,6 +19,7 @@ import { Meta, StoryObj } from '@storybook/angular';
|
|||||||
import { CardViewBoolItemComponent } from './card-view-boolitem.component';
|
import { CardViewBoolItemComponent } from './card-view-boolitem.component';
|
||||||
import { CardViewBoolItemModel } from '../../public-api';
|
import { CardViewBoolItemModel } from '../../public-api';
|
||||||
import { cardViewSharedMeta } from '../../stories/card-view-shared-meta';
|
import { cardViewSharedMeta } from '../../stories/card-view-shared-meta';
|
||||||
|
import { expect, within } from 'storybook/test';
|
||||||
|
|
||||||
const meta: Meta<CardViewBoolItemComponent> = {
|
const meta: Meta<CardViewBoolItemComponent> = {
|
||||||
...cardViewSharedMeta,
|
...cardViewSharedMeta,
|
||||||
@@ -50,5 +51,15 @@ export const CardViewBoolItem: Story = {
|
|||||||
default: false,
|
default: false,
|
||||||
editable: true
|
editable: true
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const label = canvas.getByText(/Agree to all terms and conditions/i);
|
||||||
|
await expect(label).toBeVisible();
|
||||||
|
|
||||||
|
const toggle = canvas.getByRole('checkbox');
|
||||||
|
await expect(toggle).toBeVisible();
|
||||||
|
await expect(toggle).toBeChecked();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+19
@@ -19,6 +19,7 @@ import { Meta, StoryObj } from '@storybook/angular';
|
|||||||
import { CardViewTextItemComponent } from './card-view-textitem.component';
|
import { CardViewTextItemComponent } from './card-view-textitem.component';
|
||||||
import { CardViewTextItemModel } from '../../public-api';
|
import { CardViewTextItemModel } from '../../public-api';
|
||||||
import { cardViewSharedMeta } from '../../stories/card-view-shared-meta';
|
import { cardViewSharedMeta } from '../../stories/card-view-shared-meta';
|
||||||
|
import { expect, within } from 'storybook/test';
|
||||||
|
|
||||||
const meta: Meta<CardViewTextItemComponent> = {
|
const meta: Meta<CardViewTextItemComponent> = {
|
||||||
...cardViewSharedMeta,
|
...cardViewSharedMeta,
|
||||||
@@ -50,6 +51,15 @@ export const ClickableCardViewTextItem: Story = {
|
|||||||
clickable: true,
|
clickable: true,
|
||||||
icon: 'close'
|
icon: 'close'
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const label = canvas.getByText(/CardView Text Item - Clickable template/i);
|
||||||
|
await expect(label).toBeVisible();
|
||||||
|
|
||||||
|
const value = canvas.getByText(/click here/i);
|
||||||
|
await expect(value).toBeVisible();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -104,5 +114,14 @@ export const DefaultCardViewTextItem: Story = {
|
|||||||
icon: 'close',
|
icon: 'close',
|
||||||
multiline: false
|
multiline: false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const label = canvas.getByText(/CardView Text Item - Default template/i);
|
||||||
|
await expect(label).toBeVisible();
|
||||||
|
|
||||||
|
const value = canvas.getByText(/input here/i);
|
||||||
|
await expect(value).toBeVisible();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { ADF_COMMENTS_SERVICE } from './interfaces/comments.token';
|
|||||||
import { commentsStoriesData } from './mocks/comments.stories.mock';
|
import { commentsStoriesData } from './mocks/comments.stories.mock';
|
||||||
import { CommentsServiceStoriesMock } from './mocks/comments.service.stories.mock';
|
import { CommentsServiceStoriesMock } from './mocks/comments.service.stories.mock';
|
||||||
import { provideStoryCore } from '../stories/core-story.providers';
|
import { provideStoryCore } from '../stories/core-story.providers';
|
||||||
|
import { expect, within } from 'storybook/test';
|
||||||
|
|
||||||
const meta: Meta<CommentsComponent> = {
|
const meta: Meta<CommentsComponent> = {
|
||||||
component: CommentsComponent,
|
component: CommentsComponent,
|
||||||
@@ -92,6 +93,12 @@ export const SingleCommentWithAvatar: Story = {
|
|||||||
args: {
|
args: {
|
||||||
comments: [commentsStoriesData[0]],
|
comments: [commentsStoriesData[0]],
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const commentText = canvas.getByText(/I've done this task, what's next\?/i);
|
||||||
|
await expect(commentText).toBeVisible();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,11 +119,23 @@ export const NoComments: Story = {
|
|||||||
args: {
|
args: {
|
||||||
comments: [],
|
comments: [],
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const commentElements = canvas.queryAllByText(/I've done this task/i);
|
||||||
|
await expect(commentElements.length).toBe(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Comments: Story = {
|
export const Comments: Story = {
|
||||||
render: (args) => ({
|
render: (args) => ({
|
||||||
props: args
|
props: args
|
||||||
})
|
}),
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const commentInput = canvas.getByRole('textbox');
|
||||||
|
await expect(commentInput).toBeVisible();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
import { applicationConfig, Meta, StoryObj, moduleMetadata } from '@storybook/angular';
|
import { applicationConfig, Meta, StoryObj, moduleMetadata } from '@storybook/angular';
|
||||||
import { PaginationComponent } from './pagination.component';
|
import { PaginationComponent } from './pagination.component';
|
||||||
import { provideStoryCore } from '../stories/core-story.providers';
|
import { provideStoryCore } from '../stories/core-story.providers';
|
||||||
|
import { expect, within } from 'storybook/test';
|
||||||
|
|
||||||
const meta: Meta<PaginationComponent> = {
|
const meta: Meta<PaginationComponent> = {
|
||||||
component: PaginationComponent,
|
component: PaginationComponent,
|
||||||
@@ -95,5 +96,20 @@ type Story = StoryObj<PaginationComponent>;
|
|||||||
export const Pagination: Story = {
|
export const Pagination: Story = {
|
||||||
render: (args) => ({
|
render: (args) => ({
|
||||||
props: args
|
props: args
|
||||||
})
|
}),
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const paginationRange = canvas.getByText(/1-25 of 100/i);
|
||||||
|
await expect(paginationRange).toBeVisible();
|
||||||
|
|
||||||
|
const pageSizeSelector = canvas.getByRole('combobox');
|
||||||
|
await expect(pageSizeSelector).toBeVisible();
|
||||||
|
|
||||||
|
const nextButton = canvas.getByRole('button', { name: /next/i });
|
||||||
|
await expect(nextButton).toBeVisible();
|
||||||
|
|
||||||
|
const previousButton = canvas.getByRole('button', { name: /previous/i });
|
||||||
|
await expect(previousButton).toBeVisible();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { ToolbarComponent } from './toolbar.component';
|
|||||||
import { ToolbarDividerComponent } from './toolbar-divider.component';
|
import { ToolbarDividerComponent } from './toolbar-divider.component';
|
||||||
import { ToolbarTitleComponent } from './toolbar-title.component';
|
import { ToolbarTitleComponent } from './toolbar-title.component';
|
||||||
import { provideStoryCore } from '../stories/core-story.providers';
|
import { provideStoryCore } from '../stories/core-story.providers';
|
||||||
|
import { expect, within } from 'storybook/test';
|
||||||
|
|
||||||
type ToolbarStoryArgs = ToolbarComponent & {
|
type ToolbarStoryArgs = ToolbarComponent & {
|
||||||
toolbarTitle?: boolean;
|
toolbarTitle?: boolean;
|
||||||
@@ -118,5 +119,11 @@ export const Toolbar: Story = {
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="${args.toolbarDivider}">left<adf-toolbar-divider></adf-toolbar-divider>right</ng-container>
|
<ng-container *ngIf="${args.toolbarDivider}">left<adf-toolbar-divider></adf-toolbar-divider>right</ng-container>
|
||||||
</adf-toolbar>`
|
</adf-toolbar>`
|
||||||
})
|
}),
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const toolbar = canvas.getByRole('toolbar');
|
||||||
|
await expect(toolbar).toBeVisible();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -95,6 +95,7 @@
|
|||||||
},
|
},
|
||||||
"copyToNodeModules": {
|
"copyToNodeModules": {
|
||||||
"executor": "nx:run-commands",
|
"executor": "nx:run-commands",
|
||||||
|
"cache": false,
|
||||||
"options": {
|
"options": {
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,14 +14,35 @@
|
|||||||
},
|
},
|
||||||
"stylelint": {
|
"stylelint": {
|
||||||
"cache": true
|
"cache": true
|
||||||
}
|
},
|
||||||
},
|
"build-storybook": {
|
||||||
"tasksRunnerOptions": {
|
"cache": true,
|
||||||
"default": {
|
"inputs": ["default", "^production"],
|
||||||
"runner": "nx/tasks-runners/default",
|
"outputs": ["{options.outputDir}"]
|
||||||
"options": {
|
},
|
||||||
"runtimeCacheInputs": ["node -v"]
|
"build-cjs": {
|
||||||
}
|
"cache": true,
|
||||||
|
"inputs": ["production", "^production"]
|
||||||
|
},
|
||||||
|
"build-esm2015": {
|
||||||
|
"cache": true,
|
||||||
|
"inputs": ["production", "^production"]
|
||||||
|
},
|
||||||
|
"build-esm5": {
|
||||||
|
"cache": true,
|
||||||
|
"inputs": ["production", "^production"]
|
||||||
|
},
|
||||||
|
"build-types": {
|
||||||
|
"cache": true,
|
||||||
|
"inputs": ["production", "^production"]
|
||||||
|
},
|
||||||
|
"build-schematics": {
|
||||||
|
"cache": true,
|
||||||
|
"inputs": ["production", "^production"]
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"cache": true,
|
||||||
|
"outputs": ["{workspaceRoot}/licenses.txt"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"namedInputs": {
|
"namedInputs": {
|
||||||
|
|||||||
Reference in New Issue
Block a user