Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/__shared-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ on:
permissions: {}

jobs:
test-release:
name: Test release preparation and recovery
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: $/actions/setup-node
with:
working-directory: tests/release
- run: npm test
working-directory: tests/release

linter:
uses: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml@44f6108cef0e9884ea7735f3d62932c2310745d4 # 0.39.1
permissions:
Expand Down Expand Up @@ -65,6 +80,7 @@ jobs:
needs: linter
uses: $/.github/workflows/__test-workflow-continuous-integration.yml
permissions:
actions: read
attestations: write
contents: read
packages: write
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/__test-workflow-continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ jobs:
name: Act - Run the continuous integration workflow (without container)
uses: $/.github/workflows/continuous-integration.yml
permissions:
actions: read
contents: read
id-token: write
packages: read
pull-requests: write
security-events: write
with:
working-directory: tests/npm
packages: '[{"name":"test-for-ci-with-npm","version":"0.1.0","directory":".","slug":"test-for-ci-with-npm"}]'
code-ql: |
{
"languages": "javascript-typescript",
Expand All @@ -31,6 +33,9 @@ jobs:
name: Assert - Ensure build artifact has been uploaded (without container)
runs-on: ubuntu-latest
needs: act-without-container
permissions:
actions: read
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -43,11 +48,26 @@ jobs:
- name: Check the build artifacts
run: test -f tests/npm/dist/test.txt

- name: Download the packaged CI output
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
artifact-ids: ${{ fromJSON(needs.act-without-container.outputs.package-artifacts)[0].artifact-id }}
path: ${{ runner.temp }}/ci-package
skip-decompress: true

- name: Verify the tarball contains the tested build output
env:
ARTIFACT_NAME: ${{ fromJSON(needs.act-without-container.outputs.package-artifacts)[0].artifact-name }}
run: |
tar -xOf "$RUNNER_TEMP/ci-package/$ARTIFACT_NAME" package/dist/test.txt > "$RUNNER_TEMP/packaged-build.txt"
cmp tests/npm/dist/test.txt "$RUNNER_TEMP/packaged-build.txt"

act-without-container-and-github-reports:
# jscpd:ignore-start
name: Act - Run the continuous integration workflow (without container and GitHub reports)
uses: $/.github/workflows/continuous-integration.yml
permissions:
actions: read
contents: read
id-token: write
packages: read
Expand Down Expand Up @@ -94,6 +114,7 @@ jobs:
uses: $/.github/workflows/continuous-integration.yml
needs: arrange-with-container
permissions:
actions: read
contents: read
id-token: write
packages: read
Expand Down Expand Up @@ -130,6 +151,7 @@ jobs:
uses: $/.github/workflows/continuous-integration.yml
needs: arrange-with-container
permissions:
actions: read
contents: read
id-token: write
packages: read
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/continuous-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# GitHub Reusable Workflow: Node.js Continuous Integration

<div align="center">
<img src="https://opengraph.githubassets.com/438ddeb2c21070c4705b9160e0565ec1a0c9852867a60806ea81459a5246fa2b/hoverkraft-tech/ci-github-nodejs" width="60px" align="center" alt="Node.js Continuous Integration" />
<img src="https://opengraph.githubassets.com/5e6e6522b2be37aede8ce1464ef3152618d5ae56afc61474ac0df95cbf35ec3d/hoverkraft-tech/ci-github-nodejs" width="60px" align="center" alt="Node.js Continuous Integration" />
</div>

---
Expand All @@ -16,7 +16,6 @@
[![License](https://img.shields.io/github/license/hoverkraft-tech/ci-github-nodejs)](http://choosealicense.com/licenses/mit/)
[![Stars](https://img.shields.io/github/stars/hoverkraft-tech/ci-github-nodejs?style=social)](https://img.shields.io/github/stars/hoverkraft-tech/ci-github-nodejs?style=social)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/hoverkraft-tech/ci-github-nodejs/blob/main/CONTRIBUTING.md)
![GitHub Verified Creator](https://img.shields.io/badge/GitHub-Verified%20Creator-4493F8?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJyZ2IoNjgsIDE0NywgMjQ4KSI+CiAgPHBhdGggZD0ibTkuNTg1LjUyLjkyOS42OGMuMTUzLjExMi4zMzEuMTg2LjUxOC4yMTVsMS4xMzguMTc1YTIuNjc4IDIuNjc4IDAgMCAxIDIuMjQgMi4yNGwuMTc0IDEuMTM5Yy4wMjkuMTg3LjEwMy4zNjUuMjE1LjUxOGwuNjguOTI4YTIuNjc3IDIuNjc3IDAgMCAxIDAgMy4xN2wtLjY4LjkyOGExLjE3NCAxLjE3NCAwIDAgMC0uMjE1LjUxOGwtLjE3NSAxLjEzOGEyLjY3OCAyLjY3OCAwIDAgMS0yLjI0MSAyLjI0MWwtMS4xMzguMTc1YTEuMTcgMS4xNyAwIDAgMC0uNTE4LjIxNWwtLjkyOC42OGEyLjY3NyAyLjY3NyAwIDAgMS0zLjE3IDBsLS45MjgtLjY4YTEuMTc0IDEuMTc0IDAgMCAwLS41MTgtLjIxNUwzLjgzIDE0LjQxYTIuNjc4IDIuNjc4IDAgMCAxLTIuMjQtMi4yNGwtLjE3NS0xLjEzOGExLjE3IDEuMTcgMCAwIDAtLjIxNS0uNTE4bC0uNjgtLjkyOGEyLjY3NyAyLjY3NyAwIDAgMSAwLTMuMTdsLjY4LS45MjhjLjExMi0uMTUzLjE4Ni0uMzMxLjIxNS0uNTE4bC4xNzUtMS4xNGEyLjY3OCAyLjY3OCAwIDAgMSAyLjI0LTIuMjRsMS4xMzktLjE3NWMuMTg3LS4wMjkuMzY1LS4xMDMuNTE4LS4yMTVsLjkyOC0uNjhhMi42NzcgMi42NzcgMCAwIDEgMy4xNyAwWk03LjMwMyAxLjcyOGwtLjkyNy42OGEyLjY3IDIuNjcgMCAwIDEtMS4xOC40ODlsLTEuMTM3LjE3NGExLjE3OSAxLjE3OSAwIDAgMC0uOTg3Ljk4N2wtLjE3NCAxLjEzNmEyLjY3NyAyLjY3NyAwIDAgMS0uNDg5IDEuMThsLS42OC45MjhhMS4xOCAxLjE4IDAgMCAwIDAgMS4zOTRsLjY4LjkyN2MuMjU2LjM0OC40MjQuNzUzLjQ4OSAxLjE4bC4xNzQgMS4xMzdjLjA3OC41MDkuNDc4LjkwOS45ODcuOTg3bDEuMTM2LjE3NGEyLjY3IDIuNjcgMCAwIDEgMS4xOC40ODlsLjkyOC42OGMuNDE0LjMwNS45NzkuMzA1IDEuMzk0IDBsLjkyNy0uNjhhMi42NyAyLjY3IDAgMCAxIDEuMTgtLjQ4OWwxLjEzNy0uMTc0YTEuMTggMS4xOCAwIDAgMCAuOTg3LS45ODdsLjE3NC0xLjEzNmEyLjY3IDIuNjcgMCAwIDEgLjQ4OS0xLjE4bC42OC0uOTI4YTEuMTc2IDEuMTc2IDAgMCAwIDAtMS4zOTRsLS42OC0uOTI3YTIuNjg2IDIuNjg2IDAgMCAxLS40ODktMS4xOGwtLjE3NC0xLjEzN2ExLjE3OSAxLjE3OSAwIDAgMC0uOTg3LS45ODdsLTEuMTM2LS4xNzRhMi42NzcgMi42NzcgMCAwIDEtMS4xOC0uNDg5bC0uOTI4LS42OGExLjE3NiAxLjE3NiAwIDAgMC0xLjM5NCAwWk0xMS4yOCA2Ljc4bC0zLjc1IDMuNzVhLjc1Ljc1IDAgMCAxLTEuMDYgMEw0LjcyIDguNzhhLjc1MS43NTEgMCAwIDEgLjAxOC0xLjA0Mi43NTEuNzUxIDAgMCAxIDEuMDQyLS4wMThMNyA4Ljk0bDMuMjItMy4yMmEuNzUxLjc1MSAwIDAgMSAxLjA0Mi4wMTguNzUxLjc1MSAwIDAgMSAuMDE4IDEuMDQyWiI+PC9wYXRoPgo8L3N2Zz4K)

<!-- badges:end -->

Expand All @@ -34,9 +33,11 @@ Workflow to performs continuous integration steps against a Node.js project:
- Linting
- Build
- Test
- Optional npm packaging for publication from the same commit

### Permissions

- **`actions`**: `read`
- **`contents`**: `read`
- **`id-token`**: `write`
- **`packages`**: `read`
Expand Down Expand Up @@ -253,6 +254,10 @@ jobs:
| | | | | |
| | Example: | | | |
| | <!-- textlint-disable --><pre lang="json">{&#13; "commands": [&#13; "build",&#13; "generate-artifacts"&#13; ],&#13; "env": {&#13; "CUSTOM_ENV_VAR": "value"&#13; },&#13; "artifact": [&#13; "dist/",&#13; "packages/package-a/build/"&#13; ]&#13;}</pre><!-- textlint-enable --> | | | |
| **`packages`** | Optional JSON package list from prepare-release, with name, version, directory and slug. | **false** | **string** | - |
| | Packages the build output after checks pass and returns immutable tarball artifact IDs. | | | |
| | Requires checks, a build artifact, GitHub-hosted Ubuntu runners and no container. | | | |
| | Leave empty for ordinary CI without release packaging. | | | |
| **`checks`** | Optional flag to enable check steps. | **false** | **boolean** | `true` |
| **`lint`** | Whether to enable linting. | **false** | **string** | `true` |
| | Set to `null` or empty to disable. | | | |
Expand Down Expand Up @@ -395,9 +400,10 @@ When specified, steps will execute inside this container instead of checking out

## Outputs

| **Output** | **Description** |
| ----------------------- | --------------------------------------------------------- |
| **`build-artifact-id`** | ID of the build artifact) uploaded during the build step. |
| **Output** | **Description** |
| ----------------------- | ------------------------------------------------------------------------------------------------------- |
| **`package-artifacts`** | JSON package artifact list for the release workflow in this same run. Empty when packaging is disabled. |
| **`build-artifact-id`** | ID of the build artifact) uploaded during the build step. |

<!-- outputs:end -->

Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# - Linting
# - Build
# - Test
# - Optional npm packaging for publication from the same commit

name: Node.js Continuous Integration

Expand Down Expand Up @@ -46,6 +47,14 @@ on:
type: string
required: false
default: "build"
packages:
description: |
Optional JSON package list from prepare-release, with name, version, directory and slug.
Packages the build output after checks pass and returns immutable tarball artifact IDs.
Requires checks, a build artifact, GitHub-hosted Ubuntu runners and no container.
Leave empty for ordinary CI without release packaging.
type: string
default: ""
checks:
description: "Optional flag to enable check steps."
type: boolean
Expand Down Expand Up @@ -188,6 +197,9 @@ on:
Defaults to `GITHUB_TOKEN` if not provided.
required: false
outputs:
package-artifacts:
description: JSON package artifact list for the release workflow in this same run. Empty when packaging is disabled.
value: ${{ jobs.package-artifacts.outputs.packages }}
build-artifact-id:
description: "ID of the build artifact) uploaded during the build step."
value: ${{ jobs.build.outputs.artifact-id }}
Expand All @@ -208,6 +220,18 @@ jobs:
container-username: ${{ steps.parse.outputs.container-username }}
path-mapping: ${{ steps.parse.outputs.path-mapping }}
steps:
- name: Validate packaging configuration
if: inputs.packages != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
CHECKS: ${{ inputs.checks }}
CONTAINER: ${{ inputs.container }}
RUNS_ON: ${{ inputs.runs-on }}
with:
script: |
if (process.env.CHECKS !== 'true' || process.env.CONTAINER || JSON.stringify(JSON.parse(process.env.RUNS_ON)) !== '["ubuntu-latest"]') {
core.setFailed('Release packaging requires checks, runs-on: ["ubuntu-latest"] and no container.');
}
- id: parse
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
Expand Down Expand Up @@ -606,3 +630,46 @@ jobs:
report-file: ${{ steps.prepare-test-options.outputs.report-file }}
path-mapping: ${{ needs.prepare.outputs.path-mapping || '' }}
github-token: ${{ secrets.github-token || github.token }}

package:
name: 📦 Package ${{ matrix.package.name }}
needs: [prepare, setup, build, lint, test, code-ql, dependency-review]
if: >-
${{ !cancelled() && inputs.packages != '' && needs.build.result == 'success'
&& !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
actions: read
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(inputs.packages) }}
steps:
- name: Require build output
env:
BUILD_ARTIFACT_ID: ${{ needs.build.outputs.artifact-id }}
run: test -n "$BUILD_ARTIFACT_ID"
- uses: $/actions/package
with:
working-directory: ${{ inputs.working-directory }}
package-directory: ${{ matrix.package.directory }}
build-artifact-id: ${{ needs.build.outputs.artifact-id }}
build-artifact-path: /
artifact-name: npm-${{ matrix.package.slug }}-${{ github.run_id }}-${{ github.run_attempt }}

package-artifacts:
name: 📦 Collect package artifact IDs
needs: package
if: ${{ !cancelled() && needs.package.result == 'success' }}
runs-on: ubuntu-latest
permissions:
actions: read
outputs:
packages: ${{ steps.artifacts.outputs.packages }}
steps:
- id: artifacts
uses: $/actions/package-artifacts
with:
packages: ${{ inputs.packages }}
Loading
Loading