From f17264d78a9da88014012458c6453252facca3b9 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Thu, 29 Oct 2026 21:10:57 +0200 Subject: [PATCH 1/3] ci(sassdoc): add release workflow that deploys the SassDoc Builds the SassDoc for the newest release and dispatches its deploy to IgniteUI/igniteui-actions, replacing the AZDO angular-docs-en pipeline. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/sass-docs-deploy.yml | 144 +++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .github/workflows/sass-docs-deploy.yml diff --git a/.github/workflows/sass-docs-deploy.yml b/.github/workflows/sass-docs-deploy.yml new file mode 100644 index 00000000000..da522437706 --- /dev/null +++ b/.github/workflows/sass-docs-deploy.yml @@ -0,0 +1,144 @@ +name: SassDoc deploy + +# Builds the SassDoc site for a release and hands it to IgniteUI/igniteui-actions, which deploys it +# to the internal web servers. The theme serves the site from a fixed base path +# (/products/ignite-ui-angular/docs/sass/latest/), so only the newest release is deployed: +# staging takes the newest tag, production the newest stable one. + +on: + release: + types: [published] + workflow_dispatch: + inputs: + release_tag: + description: 'Release tag to deploy the SassDoc for (e.g. 22.2.4)' + required: true + type: string + +permissions: {} + +concurrency: + group: sass-docs-deploy + +env: + VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.event.release.tag_name }} + +jobs: + resolve: + name: Resolve environments + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + environments: ${{ steps.environments.outputs.environments }} + + steps: + - name: Compare the release with the newest tags + id: environments + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + + # sort -V orders "~" before anything, so 22.2.0~rc.1 sorts below 22.2.0. + versions=$( + { gh api --paginate "repos/${GITHUB_REPOSITORY}/tags?per_page=100" --jq '.[].name'; echo "$VERSION"; } \ + | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$' \ + | sed 's/-/~/' | sort -uV | sed 's/~/-/' + ) + newest=$(tail -n1 <<< "$versions") + newest_stable=$(grep -v -- - <<< "$versions" | tail -n1) + + environments=() + if [[ "$VERSION" == "$newest" ]]; then environments+=(staging); fi + if [[ "$VERSION" == "$newest_stable" ]]; then environments+=(production); fi + + echo "environments=$(jq -nc '$ARGS.positional' --args "${environments[@]}")" >> "$GITHUB_OUTPUT" + + { + echo "### SassDoc ${VERSION}" + echo "- Newest tag: ${newest}" + echo "- Newest stable tag: ${newest_stable}" + echo "- Deploying to: ${environments[*]:-nothing, a newer release owns the docs}" + } >> "$GITHUB_STEP_SUMMARY" + + # Builds the site per environment: each one embeds its own URLs, analytics ID and header/footer. + build: + name: Build (${{ matrix.environment }}) + needs: resolve + if: needs.resolve.outputs.environments != '[]' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + strategy: + matrix: + environment: ${{ fromJSON(needs.resolve.outputs.environments) }} + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: refs/tags/${{ env.VERSION }} + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: 24.x + + - run: npm ci + + - name: Build SassDoc + run: npm run build:sassdoc:en:${{ matrix.environment }} + + - name: Upload SassDoc + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: sass-docs-${{ matrix.environment }}-${{ env.VERSION }} + path: dist/igniteui-angular/docs/sass + retention-days: 7 + if-no-files-found: error + + # Holds the app token and never runs repository code. + deploy: + name: Deploy (${{ matrix.environment }}) + needs: [resolve, build] + if: needs.resolve.outputs.environments != '[]' + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: {} + strategy: + matrix: + environment: ${{ fromJSON(needs.resolve.outputs.environments) }} + + steps: + - name: Get app token + id: app-token + uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 + with: + client-id: ${{ secrets.IGNITEUI_GITHUB_APP_CLIENT_ID }} + private-key: ${{ secrets.IGNITEUI_GITHUB_APP_PRIVATE_KEY }} + owner: IgniteUI + repositories: igniteui-actions + + # igniteui-actions downloads the artifact from this run and syncs it into angular-docs\sass\latest, + # which the site serves at /products/ignite-ui-angular/docs/sass/latest/. + - name: Trigger deploy workflow in IgniteUI Actions + uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # equivalent to release v4.0.1 + with: + token: ${{ steps.app-token.outputs.token }} + repository: IgniteUI/igniteui-actions + event-type: igniteui-angular-sass-docs-cd + client-payload: | + { + "calling_branch": "${{ github.ref }}", + "environment": "${{ matrix.environment }}", + "artifact_name": "sass-docs-${{ matrix.environment }}-${{ env.VERSION }}", + "base_href": "angular-docs\\sass\\latest", + "platform": "angular", + "repository": "${{ github.repository }}", + "run_id": "${{ github.run_id }}", + "locale": "en" + } From 94deffe8233a5567ae4005a631e421adb7e99f42 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Thu, 29 Oct 2026 21:27:42 +0200 Subject: [PATCH 2/3] ci(sassdoc): deploy each release to its version folder Every release goes to angular-docs//sass, one folder per minor line, and the newest one also to sass/latest, as the AZDO pipeline did. Staging takes every release, production stable ones only. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/sass-docs-deploy.yml | 82 ++++++++++++++++++-------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/.github/workflows/sass-docs-deploy.yml b/.github/workflows/sass-docs-deploy.yml index da522437706..ff2d288259d 100644 --- a/.github/workflows/sass-docs-deploy.yml +++ b/.github/workflows/sass-docs-deploy.yml @@ -1,9 +1,8 @@ name: SassDoc deploy # Builds the SassDoc site for a release and hands it to IgniteUI/igniteui-actions, which deploys it -# to the internal web servers. The theme serves the site from a fixed base path -# (/products/ignite-ui-angular/docs/sass/latest/), so only the newest release is deployed: -# staging takes the newest tag, production the newest stable one. +# under angular-docs on the internal web servers: to /sass, one folder per minor line, and +# to sass/latest for the newest release. Staging takes every release, production stable ones only. on: release: @@ -17,8 +16,9 @@ on: permissions: {} +# One run per release. Runs for different releases go ahead, and their deploys queue in igniteui-actions. concurrency: - group: sass-docs-deploy + group: sass-docs-deploy-${{ github.event.release.tag_name || inputs.release_tag }} env: VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.event.release.tag_name }} @@ -31,7 +31,7 @@ jobs: permissions: contents: read outputs: - environments: ${{ steps.environments.outputs.environments }} + include: ${{ steps.environments.outputs.include }} steps: - name: Compare the release with the newest tags @@ -41,40 +41,55 @@ jobs: run: | set -euo pipefail + if [[ ! "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then + echo "::error::${VERSION} is not a release version." + exit 1 + fi + minor_line="^${BASH_REMATCH[1]}\.${BASH_REMATCH[2]}\." + # sort -V orders "~" before anything, so 22.2.0~rc.1 sorts below 22.2.0. - versions=$( + all=$( { gh api --paginate "repos/${GITHUB_REPOSITORY}/tags?per_page=100" --jq '.[].name'; echo "$VERSION"; } \ | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$' \ | sed 's/-/~/' | sort -uV | sed 's/~/-/' ) - newest=$(tail -n1 <<< "$versions") - newest_stable=$(grep -v -- - <<< "$versions" | tail -n1) - - environments=() - if [[ "$VERSION" == "$newest" ]]; then environments+=(staging); fi - if [[ "$VERSION" == "$newest_stable" ]]; then environments+=(production); fi + stable=$(grep -v -- - <<< "$all") + + # A release owns its minor line's folder while it is the newest of that line, + # and sass/latest while it is the newest overall. + entries=() + add() { + local environment=$1 versions=$2 latest=false + if [[ "$VERSION" != "$(grep -E "$minor_line" <<< "$versions" | tail -n1)" ]]; then return 0; fi + if [[ "$VERSION" == "$(tail -n1 <<< "$versions")" ]]; then latest=true; fi + entries+=("{\"environment\":\"${environment}\",\"latest\":${latest}}") + } + add staging "$all" + if [[ "$VERSION" != *-* ]]; then add production "$stable"; fi - echo "environments=$(jq -nc '$ARGS.positional' --args "${environments[@]}")" >> "$GITHUB_OUTPUT" + include=$(printf '%s\n' "${entries[@]}" | jq -sc .) + echo "include=${include}" >> "$GITHUB_OUTPUT" { echo "### SassDoc ${VERSION}" - echo "- Newest tag: ${newest}" - echo "- Newest stable tag: ${newest_stable}" - echo "- Deploying to: ${environments[*]:-nothing, a newer release owns the docs}" + echo "Newest tag: $(tail -n1 <<< "$all"), newest stable tag: $(tail -n1 <<< "$stable")" + echo + jq -r '.[] | "- \(.environment): \(if .latest then "version folder and latest" else "version folder" end)"' <<< "$include" + if [[ "$include" == "[]" ]]; then echo "Nothing to deploy, a newer release of this minor line exists."; fi } >> "$GITHUB_STEP_SUMMARY" # Builds the site per environment: each one embeds its own URLs, analytics ID and header/footer. build: name: Build (${{ matrix.environment }}) needs: resolve - if: needs.resolve.outputs.environments != '[]' + if: needs.resolve.outputs.include != '[]' runs-on: ubuntu-latest timeout-minutes: 30 permissions: contents: read strategy: matrix: - environment: ${{ fromJSON(needs.resolve.outputs.environments) }} + include: ${{ fromJSON(needs.resolve.outputs.include) }} steps: - name: Checkout @@ -93,11 +108,29 @@ jobs: - name: Build SassDoc run: npm run build:sassdoc:en:${{ matrix.environment }} + # Lays the site out as it goes under angular-docs: the version folder, kept out of search + # results like the earlier ones, and sass/latest when this release is the newest. + - name: Stage the angular-docs folders + env: + LATEST: ${{ matrix.latest }} + run: | + set -euo pipefail + + mkdir -p "angular-docs/${VERSION}" + cp -r dist/igniteui-angular/docs/sass "angular-docs/${VERSION}/sass" + find "angular-docs/${VERSION}/sass" -name index.html \ + -exec sed -i 's|||' {} + + + if [[ "$LATEST" == "true" ]]; then + mkdir -p angular-docs/sass + cp -r dist/igniteui-angular/docs/sass angular-docs/sass/latest + fi + - name: Upload SassDoc uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: sass-docs-${{ matrix.environment }}-${{ env.VERSION }} - path: dist/igniteui-angular/docs/sass + path: angular-docs retention-days: 7 if-no-files-found: error @@ -105,13 +138,13 @@ jobs: deploy: name: Deploy (${{ matrix.environment }}) needs: [resolve, build] - if: needs.resolve.outputs.environments != '[]' + if: needs.resolve.outputs.include != '[]' runs-on: ubuntu-latest timeout-minutes: 10 permissions: {} strategy: matrix: - environment: ${{ fromJSON(needs.resolve.outputs.environments) }} + include: ${{ fromJSON(needs.resolve.outputs.include) }} steps: - name: Get app token @@ -123,8 +156,8 @@ jobs: owner: IgniteUI repositories: igniteui-actions - # igniteui-actions downloads the artifact from this run and syncs it into angular-docs\sass\latest, - # which the site serves at /products/ignite-ui-angular/docs/sass/latest/. + # igniteui-actions downloads the artifact from this run, syncs its folders into angular-docs, + # removes the other folders of this minor line and refreshes the version selector's list. - name: Trigger deploy workflow in IgniteUI Actions uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # equivalent to release v4.0.1 with: @@ -136,7 +169,8 @@ jobs: "calling_branch": "${{ github.ref }}", "environment": "${{ matrix.environment }}", "artifact_name": "sass-docs-${{ matrix.environment }}-${{ env.VERSION }}", - "base_href": "angular-docs\\sass\\latest", + "version": "${{ env.VERSION }}", + "latest": ${{ matrix.latest }}, "platform": "angular", "repository": "${{ github.repository }}", "run_id": "${{ github.run_id }}", From 7b19f2c65583f65a1ee04db9bdcc7887137217f3 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Fri, 30 Oct 2026 12:40:15 +0200 Subject: [PATCH 3/3] ci(sassdoc): keep the SassDoc artifact for one day Co-Authored-By: Claude Opus 5.5 --- .github/workflows/sass-docs-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sass-docs-deploy.yml b/.github/workflows/sass-docs-deploy.yml index ff2d288259d..6cc64402bfd 100644 --- a/.github/workflows/sass-docs-deploy.yml +++ b/.github/workflows/sass-docs-deploy.yml @@ -131,7 +131,7 @@ jobs: with: name: sass-docs-${{ matrix.environment }}-${{ env.VERSION }} path: angular-docs - retention-days: 7 + retention-days: 1 if-no-files-found: error # Holds the app token and never runs repository code.