diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml index e22b9804cd..3297f45d8c 100644 --- a/.github/workflows/browserstack.yml +++ b/.github/workflows/browserstack.yml @@ -22,12 +22,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" cache: npm diff --git a/.github/workflows/bundlewatch.yml b/.github/workflows/bundlewatch.yml index f196df1b88..85450a36e5 100644 --- a/.github/workflows/bundlewatch.yml +++ b/.github/workflows/bundlewatch.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" cache: npm diff --git a/.github/workflows/calibreapp-image-actions.yml b/.github/workflows/calibreapp-image-actions.yml index 08987b3aae..11ee729287 100644 --- a/.github/workflows/calibreapp-image-actions.yml +++ b/.github/workflows/calibreapp-image-actions.yml @@ -22,11 +22,11 @@ jobs: pull-requests: write steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Compress Images - uses: calibreapp/image-actions@1.1.0 + uses: calibreapp/image-actions@737ceeaeed61e17b8d358358a303f1b8d177b779 # v1.1.0 with: githubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dd7f6e7ef8..ca3a388344 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,21 +24,21 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # v3.29.5 with: config-file: ./.github/codeql/codeql-config.yml languages: "javascript" queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # v3.29.5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # v3.29.5 with: category: "/language:javascript" diff --git a/.github/workflows/cspell.yml b/.github/workflows/cspell.yml index 44eb025fd8..4412eb90a8 100644 --- a/.github/workflows/cspell.yml +++ b/.github/workflows/cspell.yml @@ -23,12 +23,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Run cspell - uses: streetsidesoftware/cspell-action@v7 + uses: streetsidesoftware/cspell-action@dcd03dc3e8a59ec2e360d0c62db517baa0b4bb6d # v7.2.0 with: config: ".cspell.json" files: "**/*.{md,mdx}" diff --git a/.github/workflows/css.yml b/.github/workflows/css.yml index 1c231ac88b..90951d6c81 100644 --- a/.github/workflows/css.yml +++ b/.github/workflows/css.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" cache: npm diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d7c88aeb0c..6134833523 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" cache: npm @@ -42,7 +42,7 @@ jobs: run: npm run docs-vnu - name: Run linkinator - uses: JustinBeckwith/linkinator-action@v1 + uses: JustinBeckwith/linkinator-action@3d5ba091319fa7b0ac14703761eebb7d100e6f6d # v1.11.0 with: paths: _site recurse: true diff --git a/.github/workflows/issue-close-require.yml b/.github/workflows/issue-close-require.yml index b5000d8b43..7351fa067b 100644 --- a/.github/workflows/issue-close-require.yml +++ b/.github/workflows/issue-close-require.yml @@ -17,7 +17,7 @@ jobs: if: github.repository == 'twbs/bootstrap' steps: - name: awaiting reply - uses: actions-cool/issues-helper@v3 + uses: actions-cool/issues-helper@50068f49b7b2b3857270ead65e2d02e4459b022c # v3.6.2 with: actions: "close-issues" labels: "awaiting-reply" diff --git a/.github/workflows/issue-labeled.yml b/.github/workflows/issue-labeled.yml index 584879dd80..92569dff84 100644 --- a/.github/workflows/issue-labeled.yml +++ b/.github/workflows/issue-labeled.yml @@ -18,7 +18,7 @@ jobs: steps: - name: awaiting reply if: github.event.label.name == 'needs-example' - uses: actions-cool/issues-helper@v3 + uses: actions-cool/issues-helper@50068f49b7b2b3857270ead65e2d02e4459b022c # v3.6.2 with: actions: "create-comment" token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index fdc24889b1..d720ab6f0f 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -25,12 +25,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: ${{ env.NODE }} cache: npm @@ -45,7 +45,7 @@ jobs: run: npm run js-test - name: Run Coveralls - uses: coverallsapp/github-action@v2 + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6 if: ${{ !github.event.repository.fork }} with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1c7aa54f55..e2c5cc9fb7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" cache: npm diff --git a/.github/workflows/node-sass.yml b/.github/workflows/node-sass.yml index bdb7dbeaf4..33478df4f0 100644 --- a/.github/workflows/node-sass.yml +++ b/.github/workflows/node-sass.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "${{ env.NODE }}" diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml index 813956af20..d37d5e8412 100644 --- a/.github/workflows/release-notes.yml +++ b/.github/workflows/release-notes.yml @@ -18,6 +18,6 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'twbs/bootstrap' steps: - - uses: release-drafter/release-drafter@v6 + - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000000..bb487ade12 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,78 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '27 12 * * 2' + push: + branches: [ "main" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled. + if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + # Uncomment the permissions below if installing in a private repository. + # contents: read + # actions: read + + steps: + - name: "Checkout code" + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore + # file_mode: git + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # v3.29.5 + with: + sarif_file: results.sarif diff --git a/README.md b/README.md index d996246bdc..0dbcf41092 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-starte [](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css) [](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js) [](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js) + [](#backers) [](#sponsors) diff --git a/build/zip-examples.mjs b/build/zip-examples.mjs index 03995efd53..6b2e1e0dac 100644 --- a/build/zip-examples.mjs +++ b/build/zip-examples.mjs @@ -11,6 +11,7 @@ import fs from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' import sh from 'shelljs' +import { format } from 'prettier' const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -83,7 +84,9 @@ for (const file of staticJsFiles) { sh.rm(`${distFolder}/index.html`) // get all examples' HTML files -for (const file of sh.find(`${distFolder}/**/*.html`)) { +const htmlFiles = sh.find(`${distFolder}/**/*.html`) + +const formatPromises = htmlFiles.map(async file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') @@ -91,8 +94,24 @@ for (const file of sh.find(`${distFolder}/**/*.html`)) { .replace(/(]*) integrity="[^"]*"/g, '$1') .replace(/]*href="\.\.\/assets\/img\/favicons\/[^"]*"[^>]*>/g, '') .replace(/( -
>
)
}