Skip to content
Merged
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
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
groups:
npm-non-major:
patterns:
- "*"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 3
groups:
github-actions:
patterns:
- "*"
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ on:
branches:
- main
workflow_dispatch:
inputs:
base_ref:
description: "Optional base ref for dependency review when dispatched manually"
required: false
type: string
head_ref:
description: "Optional head ref for dependency review when dispatched manually"
required: false
type: string

permissions:
contents: read
Expand All @@ -15,9 +24,27 @@ concurrency:
cancel-in-progress: true

jobs:
dependency-review:
if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.base_ref != '' && inputs.head_ref != '')
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd

- name: Run dependency review
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48
with:
base-ref: ${{ inputs.base_ref || '' }}
head-ref: ${{ inputs.head_ref || '' }}

validate:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CodeQL

on:
pull_request:
paths-ignore:
- dist/**
- test/fixtures/**
- .cstack/**
push:
branches:
- main
paths-ignore:
- dist/**
- test/fixtures/**
- .cstack/**
schedule:
- cron: "17 4 * * 1"
workflow_dispatch:

permissions:
contents: read
security-events: write

concurrency:
group: codeql-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: CodeQL
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
with:
fetch-depth: 0

- name: Initialize CodeQL
uses: github/codeql-action/init@ebcb5b36ded6beda4ceefea6a8bc4cc885255bb3
with:
languages: javascript-typescript
build-mode: none

- name: Analyze
uses: github/codeql-action/analyze@ebcb5b36ded6beda4ceefea6a8bc4cc885255bb3
102 changes: 83 additions & 19 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ on:
required: true
type: string

permissions:
actions: write
contents: write

concurrency:
group: prepare-release-${{ inputs.version }}
cancel-in-progress: false

jobs:
prepare-release:
runs-on: ubuntu-latest
permissions:
actions: write
contents: write
env:
VERSION: ${{ inputs.version }}
TAG: v${{ inputs.version }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
REPOSITORY: ${{ github.repository }}
steps:
- name: Check out default branch
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
Expand Down Expand Up @@ -62,7 +62,9 @@ jobs:
run: npm ci

- name: Check current package version
run: echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> "$GITHUB_ENV"
run: |
echo "CURRENT_VERSION=$(node -p 'require(\"./package.json\").version')" >> "$GITHUB_ENV"
echo "BASE_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"

- name: Bump package version
shell: bash
Expand Down Expand Up @@ -110,30 +112,92 @@ jobs:
if: steps.commit.outputs.created == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: gh workflow run ci.yml --ref "${DEFAULT_BRANCH}"
run: |
RELEASE_SHA="$(git rev-parse HEAD)"
gh workflow run ci.yml \
--ref "${DEFAULT_BRANCH}" \
-f base_ref="${BASE_SHA}" \
-f head_ref="${RELEASE_SHA}"

- name: Dispatch CodeQL for pushed release commit
if: steps.commit.outputs.created == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: gh workflow run codeql.yml --ref "${DEFAULT_BRANCH}"

- name: Dispatch Gitleaks for pushed release commit
if: steps.commit.outputs.created == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: gh workflow run secrets.yml --ref "${DEFAULT_BRANCH}"

- name: Wait for required CI on pushed release commit
- name: Wait for required checks on pushed release commit
if: steps.commit.outputs.created == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
shell: bash
run: |
REQUIRED_CHECKS=("validate" "dependency-review" "CodeQL" "Gitleaks")
RELEASE_SHA="$(git rev-parse HEAD)"
RUN_ID=""
for attempt in $(seq 1 30); do
RUN_ID="$(gh run list --workflow ci.yml --commit "${RELEASE_SHA}" --json databaseId --jq '.[0].databaseId // empty' || true)"
if [ -n "${RUN_ID}" ]; then
break
MAX_ATTEMPTS=180

get_check_state() {
local check_name="$1"
gh api "repos/${REPOSITORY}/commits/${RELEASE_SHA}/check-runs?per_page=100" \
| jq -r --arg name "${check_name}" '
[.check_runs[]
| select(.name == $name)
| {id, status, conclusion}]
| sort_by(.id)
| last
| if . == null then
"missing\t"
else
"\(.status)\t\(.conclusion // "")"
end
'
}

for _ in $(seq 1 "${MAX_ATTEMPTS}"); do
pending_checks=()
failed_checks=()

for check_name in "${REQUIRED_CHECKS[@]}"; do
check_state="$(get_check_state "${check_name}" || true)"
check_status="${check_state%%$'\t'*}"
check_conclusion="${check_state#*$'\t'}"

if [ -z "${check_state}" ] || [ "${check_status}" = "missing" ]; then
pending_checks+=("${check_name}")
continue
fi

if [ "${check_status}" != "completed" ]; then
pending_checks+=("${check_name}")
continue
fi

if [ "${check_conclusion}" != "success" ]; then
failed_checks+=("${check_name}:${check_conclusion:-unknown}")
fi
done

if [ "${#failed_checks[@]}" -gt 0 ]; then
printf 'Required check failure(s): %s\n' "${failed_checks[*]}"
exit 1
fi
sleep 3
done

if [ -z "${RUN_ID}" ]; then
echo "Required CI run was not found for ${RELEASE_SHA}"
exit 1
fi
if [ "${#pending_checks[@]}" -eq 0 ]; then
echo "All required checks passed for ${RELEASE_SHA}."
exit 0
fi

echo "Waiting for required checks: ${pending_checks[*]}"
sleep 10
done

gh run watch "${RUN_ID}" --exit-status
echo "Timed out waiting for required checks on ${RELEASE_SHA}."
exit 1

- name: Create release tag
run: git tag "${TAG}"
Expand Down
36 changes: 32 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ on:
required: true
type: string

permissions:
contents: write

concurrency:
group: release-${{ github.ref_name }}
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
attestations: write
artifact-metadata: write
id-token: write
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
Expand Down Expand Up @@ -48,7 +50,7 @@ jobs:
- name: Validate package version matches tag
shell: bash
run: |
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
PACKAGE_VERSION="$(node -p 'require(\"./package.json\").version')"
EXPECTED_TAG="v${PACKAGE_VERSION}"
if [ "${EXPECTED_TAG}" != "${RELEASE_TAG}" ]; then
echo "package.json version ${PACKAGE_VERSION} does not match tag ${RELEASE_TAG}"
Expand Down Expand Up @@ -76,6 +78,13 @@ jobs:
cp "release/${PACKAGE_FILE}" "release/cstack-latest.tgz"
echo "PACKAGE_FILE=${PACKAGE_FILE}" >> "$GITHUB_ENV"

- name: Record release artifact paths
id: release_paths
shell: bash
run: |
echo "package_file=${PACKAGE_FILE}" >> "$GITHUB_OUTPUT"
echo "sbom_file=release/cstack-${PACKAGE_VERSION}.sbom.spdx.json" >> "$GITHUB_OUTPUT"

- name: Smoke-test packaged install
shell: bash
run: |
Expand All @@ -85,6 +94,22 @@ jobs:
npm install -g "./release/${PACKAGE_FILE}" --prefix "${INSTALL_ROOT}"
"${INSTALL_ROOT}/bin/cstack" --help >/dev/null

- name: Generate SBOM
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610
with:
file: release/${{ steps.release_paths.outputs.package_file }}
format: spdx-json
output-file: ${{ steps.release_paths.outputs.sbom_file }}
upload-artifact: false
upload-release-assets: false

- name: Create provenance attestation
uses: actions/attest-build-provenance@b3e506e8c389afc651c5bacf2b8f2a1ea0557215
with:
subject-path: |
release/${{ steps.release_paths.outputs.package_file }}
release/cstack-latest.tgz

- name: Generate checksums
shell: bash
run: |
Expand Down Expand Up @@ -132,6 +157,7 @@ jobs:
- packaged CLI entrypoint
- compiled \`dist/\` runtime
- current README and install guidance
- SBOM and provenance attestation for the published tarball

## Quick start

Expand All @@ -151,6 +177,7 @@ jobs:
"release/${PACKAGE_FILE}" \
"release/cstack-latest.tgz" \
"release/SHA256SUMS.txt" \
"${{ steps.release_paths.outputs.sbom_file }}" \
--clobber
gh release edit "${RELEASE_TAG}" \
--title "cstack ${RELEASE_TAG}" \
Expand All @@ -160,6 +187,7 @@ jobs:
"release/${PACKAGE_FILE}" \
"release/cstack-latest.tgz" \
"release/SHA256SUMS.txt" \
"${{ steps.release_paths.outputs.sbom_file }}" \
--title "cstack ${RELEASE_TAG}" \
--notes-file release/RELEASE_NOTES.md
fi
40 changes: 40 additions & 0 deletions .github/workflows/secrets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Gitleaks

on:
pull_request:
paths-ignore:
- dist/**
- test/fixtures/**
- .cstack/**
push:
branches:
- main
paths-ignore:
- dist/**
- test/fixtures/**
- .cstack/**
workflow_dispatch:

permissions:
contents: read

concurrency:
group: gitleaks-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
scan:
name: Gitleaks
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
with:
fetch-depth: 0

- name: Scan for secrets
uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7
env:
GITHUB_TOKEN: ${{ github.token }}
GITLEAKS_ENABLE_COMMENTS: false
Loading
Loading