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
29 changes: 5 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
code: ${{ steps.classify.outputs.code }}
drizzle: ${{ steps.classify.outputs.drizzle }}
tutorial: ${{ steps.classify.outputs.tutorial }}
docs: ${{ steps.classify.outputs.docs }}
steps:
- name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Expand All @@ -40,38 +41,18 @@ jobs:
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
if [[ "${{ github.event_name }}" == schedule ]]; then
{ echo 'code=false'; echo 'drizzle=false'; echo 'tutorial=true'; } >> "$GITHUB_OUTPUT"
{ echo 'code=false'; echo 'drizzle=false'; echo 'tutorial=true'; echo 'docs=false'; } >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "${{ github.event_name }}" == workflow_dispatch || "$BASE" =~ ^0+$ ]]; then
{ echo 'code=true'; echo 'drizzle=true'; echo 'tutorial=true'; } >> "$GITHUB_OUTPUT"
{ echo 'code=true'; echo 'drizzle=true'; echo 'tutorial=true'; echo 'docs=false'; } >> "$GITHUB_OUTPUT"
exit 0
fi
files=$(git diff --name-only "$BASE" HEAD)
if [[ -z "$files" ]]; then
echo 'No changed files to classify' >&2
exit 2
fi
code=false
drizzle=false
tutorial=false
while IFS= read -r file; do
case "$file" in
Documentation/client-snippets/tutorial/*|Documentation/client-snippets/arc-without-event-sourcing/*|Documentation/tutorial-e2e/*|Documentation/validate-client-snippets.py|Source/MongoDB/*|Source/Core/*|Source/Tools/ProxyGenerator/*|.github/workflows/ci.yml|package.json|yarn.lock) tutorial=true ;;
esac
case "$file" in
Source/Drizzle/*|Documentation/sql/observing-postgresql.md|.github/workflows/ci.yml|package.json|yarn.lock) drizzle=true ;;
esac
case "$file" in
Documentation/*|*.md) ;;
*) code=true ;;
esac
done <<< "$files"
{ echo "code=$code"; echo "drizzle=$drizzle"; echo "tutorial=$tutorial"; } >> "$GITHUB_OUTPUT"
git diff --name-only "$BASE" HEAD | bash scripts/classify-changes.sh >> "$GITHUB_OUTPUT"

docs:
needs: changes
if: needs.changes.outputs.code == 'false' && github.event_name != 'schedule'
if: needs.changes.outputs.docs == 'true'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"set-version": "node scripts/set-version.mjs",
"test": "vitest run",
"specs": "yarn test",
"ci": "yarn tsc -b Source/Core Source/Testing Source/Chronicle Source/Tools/ProxyGenerator && yarn check:metadata && yarn workspace @cratis/arc.core.sample.tasks generate-proxies && yarn workspace @cratis/arc.sample.library generate-proxies && yarn check:proxies && yarn build && yarn check:declarations && yarn check:declarations:self-test && yarn check:consumers && yarn check:chronicle-peer-floor:self-test && yarn check:chronicle-peer-floor && yarn check:fetch && yarn check:node-test && yarn check:observability-recipes && yarn workspace @cratis/arc.sample.library.web build && yarn lint && yarn typecheck && yarn lint:tasks:arc && yarn test:client-generation:verify && yarn test && yarn workspace @cratis/arc.sample.library test:e2e && yarn test:legacy-decorators && yarn test:decorator-types && yarn docs:lint && yarn docs:snippets:self-test && yarn docs:snippets && yarn docs:examples:self-test && yarn docs:examples && node --test scripts/for_release/*.test.mjs && yarn set-version --check"
"ci": "yarn tsc -b Source/Core Source/Testing Source/Chronicle Source/Tools/ProxyGenerator && yarn check:metadata && yarn workspace @cratis/arc.core.sample.tasks generate-proxies && yarn workspace @cratis/arc.sample.library generate-proxies && yarn check:proxies && yarn build && yarn check:declarations && yarn check:declarations:self-test && yarn check:consumers && yarn check:chronicle-peer-floor:self-test && yarn check:chronicle-peer-floor && yarn check:fetch && yarn check:node-test && yarn check:observability-recipes && yarn workspace @cratis/arc.sample.library.web build && yarn lint && yarn typecheck && yarn lint:tasks:arc && yarn test:client-generation:verify && yarn test && yarn workspace @cratis/arc.sample.library test:e2e && yarn test:legacy-decorators && yarn test:decorator-types && yarn docs:lint && yarn docs:snippets:self-test && yarn docs:snippets && yarn docs:examples:self-test && yarn docs:examples && node --test scripts/for_release/*.test.mjs && node --test scripts/classify-changes.test.mjs && yarn set-version --check"
},
"devDependencies": {
"@cratis/arc.react": "22.19.1",
Expand Down
34 changes: 34 additions & 0 deletions scripts/classify-changes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Copyright (c) Cratis. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
# Reads changed file paths (one per line) from stdin and prints the CI job selection as
# key=value lines. An empty list (for example a pull request whose changes are already on
# the base branch) selects nothing, so every downstream job is skipped.
set -euo pipefail

code=false
drizzle=false
tutorial=false
docs=false
seen=false

while IFS= read -r file || [[ -n "$file" ]]; do
[[ -z "$file" ]] && continue
seen=true
case "$file" in
Documentation/client-snippets/tutorial/*|Documentation/client-snippets/arc-without-event-sourcing/*|Documentation/tutorial-e2e/*|Documentation/validate-client-snippets.py|Source/MongoDB/*|Source/Core/*|Source/Tools/ProxyGenerator/*|.github/workflows/ci.yml|package.json|yarn.lock) tutorial=true ;;
esac
case "$file" in
Source/Drizzle/*|Documentation/sql/observing-postgresql.md|.github/workflows/ci.yml|package.json|yarn.lock) drizzle=true ;;
esac
case "$file" in
Documentation/*|*.md) ;;
*) code=true ;;
esac
done

if [[ "$seen" == true && "$code" == false ]]; then
docs=true
fi

printf 'code=%s\ndrizzle=%s\ntutorial=%s\ndocs=%s\n' "$code" "$drizzle" "$tutorial" "$docs"
38 changes: 38 additions & 0 deletions scripts/classify-changes.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Cratis. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const script = join(dirname(fileURLToPath(import.meta.url)), 'classify-changes.sh');

function classify(files) {
const result = spawnSync('bash', [script], { input: files.join('\n'), encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr);
return Object.fromEntries(result.stdout.trim().split('\n').map(line => line.split('=')));
}

test('when there are no changed files, nothing is selected', () => {
assert.deepEqual(classify([]), { code: 'false', drizzle: 'false', tutorial: 'false', docs: 'false' });
});

test('when only blank lines are given, nothing is selected', () => {
assert.deepEqual(classify(['', '']), { code: 'false', drizzle: 'false', tutorial: 'false', docs: 'false' });
});

test('when only documentation changed, only the documentation check is selected', () => {
assert.deepEqual(classify(['README.md', 'Documentation/index.md']), { code: 'false', drizzle: 'false', tutorial: 'false', docs: 'true' });
});

test('when source changed, the complete gate is selected instead of the documentation check', () => {
assert.deepEqual(classify(['Source/Chronicle/index.ts']), { code: 'true', drizzle: 'false', tutorial: 'false', docs: 'false' });
});

test('when core, drizzle and lock file changed, the matching integrations are selected', () => {
const result = classify(['Source/Core/a.ts', 'Source/Drizzle/b.ts']);
assert.equal(result.tutorial, 'true');
assert.equal(result.drizzle, 'true');
assert.equal(result.code, 'true');
});
Loading