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
40 changes: 26 additions & 14 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,18 @@ jobs:
- uses: actions/checkout@v6.0.2
with:
ref: ${{ needs.auto-format.outputs.sha }}
fetch-depth: 1
persist-credentials: false

- name: Configure Git for HTTPS with Token
shell: bash
env:
GH_PAT: ${{ secrets.TSAVO_AT_PIECES_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
run: |
git config --global url."https://x-access-token:${GH_PAT}@github.com/".insteadOf "git@github.com:"
git config --global url."https://x-access-token:${GH_PAT}@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://x-access-token:${GH_PAT}@github.com/open-runtime/".insteadOf "git@github.com:open-runtime/"
git config --global url."https://x-access-token:${GH_PAT}@github.com/pieces-app/".insteadOf "git@github.com:pieces-app/"
TOKEN="${{ secrets.TSAVO_AT_PIECES_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}"
echo "::add-mask::${TOKEN}"
git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "git@github.com:"
git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://x-access-token:${TOKEN}@github.com/open-runtime/".insteadOf "git@github.com:open-runtime/"
git config --global url."https://x-access-token:${TOKEN}@github.com/pieces-app/".insteadOf "git@github.com:pieces-app/"

- uses: dart-lang/setup-dart@v1.7.1
with:
Expand All @@ -114,8 +115,8 @@ jobs:

- name: Analyze
run: |
dart analyze 2>&1 | tee /tmp/analysis.txt
if grep -q "^ error -" /tmp/analysis.txt; then
dart analyze 2>&1 | tee "$RUNNER_TEMP/analysis.txt"
if grep -q "^ error -" "$RUNNER_TEMP/analysis.txt"; then
echo "::error::Analysis errors found"
exit 1
fi
Expand All @@ -132,17 +133,18 @@ jobs:
- uses: actions/checkout@v6.0.2
with:
ref: ${{ needs.auto-format.outputs.sha }}
fetch-depth: 1
persist-credentials: false

- name: Configure Git for HTTPS with Token
shell: bash
env:
GH_PAT: ${{ secrets.TSAVO_AT_PIECES_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
run: |
git config --global url."https://x-access-token:${GH_PAT}@github.com/".insteadOf "git@github.com:"
git config --global url."https://x-access-token:${GH_PAT}@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://x-access-token:${GH_PAT}@github.com/open-runtime/".insteadOf "git@github.com:open-runtime/"
git config --global url."https://x-access-token:${GH_PAT}@github.com/pieces-app/".insteadOf "git@github.com:pieces-app/"
TOKEN="${{ secrets.TSAVO_AT_PIECES_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}"
echo "::add-mask::${TOKEN}"
git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "git@github.com:"
git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "ssh://git@github.com/"
git config --global url."https://x-access-token:${TOKEN}@github.com/open-runtime/".insteadOf "git@github.com:open-runtime/"
git config --global url."https://x-access-token:${TOKEN}@github.com/pieces-app/".insteadOf "git@github.com:pieces-app/"

- uses: dart-lang/setup-dart@v1.7.1
with:
Expand All @@ -165,6 +167,16 @@ jobs:
- name: Test
run: dart test

- name: Upload test artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{ matrix.platform_id }}
path: |
test/integration/fixtures/bin/
**/test-results/
retention-days: 7

# --- BEGIN USER: post-test ---
# --- END USER: post-test ---

Expand Down
15 changes: 7 additions & 8 deletions lib/src/cli/commands/autodoc_command.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:args/command_runner.dart';
import 'package:crypto/crypto.dart';
Expand Down Expand Up @@ -482,26 +483,24 @@ Write the corrected file to the same path: $absOutputFile

filePaths.sort();

final sink = AccumulatorSink<Digest>();
final input = sha256.startChunkedConversion(sink);
final builder = BytesBuilder(copy: false);

for (final path in filePaths) {
// Include the path name in the digest so renames affect the hash.
input.add(utf8.encode(path));
input.add(const [0]);
builder.add(utf8.encode(path));
builder.addByte(0);

if (!path.startsWith('missing_dir:')) {
try {
input.add(File(path).readAsBytesSync());
builder.add(File(path).readAsBytesSync());
} catch (e) {
Logger.warn('Could not read $path for module hash: $e');
}
}

input.add(const [0]);
builder.addByte(0);
}

input.close();
return sink.events.single.toString();
return sha256.convert(builder.takeBytes()).toString();
}
Comment on lines +486 to 505
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_computeModuleHash now concatenates every file path and file's bytes into a single BytesBuilder before hashing. For large repos/modules this can significantly increase memory usage compared to streaming/chunked hashing. Consider using sha256.startChunkedConversion(...) (or another streaming approach) and add each file's bytes incrementally so the peak memory stays bounded.

Copilot uses AI. Check for mistakes.
}
18 changes: 7 additions & 11 deletions lib/src/cli/utils/template_manifest.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:convert';
import 'dart:io';

import 'package:crypto/crypto.dart';

import '../../triage/utils/run_context.dart';

/// Represents one template entry from manifest.json.
Expand Down Expand Up @@ -96,18 +98,12 @@ class TemplateVersionTracker {
}

/// Compute SHA256 hash of a file's contents.
///
/// Uses pure Dart [sha256] from `package:crypto` so it works on all platforms
/// (macOS, Linux, Windows) without shelling out to external tools.
String computeFileHash(String filePath) {
final file = File(filePath);
if (!file.existsSync()) return '';
// Try shasum (macOS) first, then sha256sum (Linux)
final macResult = Process.runSync('sh', ['-c', 'shasum -a 256 "$filePath" | cut -d" " -f1']);
if (macResult.exitCode == 0) {
final hash = (macResult.stdout as String).trim();
if (hash.isNotEmpty) return hash;
}
final linuxResult = Process.runSync('sh', ['-c', 'sha256sum "$filePath" | cut -d" " -f1']);
if (linuxResult.exitCode == 0) {
return (linuxResult.stdout as String).trim();
}
return '';
final bytes = file.readAsBytesSync();
return sha256.convert(bytes).toString();
}
5 changes: 5 additions & 0 deletions lib/src/cli/utils/workflow_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ class WorkflowGenerator {
/// `# --- BEGIN USER: <name> ---`
/// `# --- END USER: <name> ---`
String _preserveUserSections(String rendered, String existing) {
// Normalize CRLF → LF so the regex matches regardless of line-ending style
// (Windows checkouts with core.autocrlf=true produce \r\n).
existing = existing.replaceAll('\r\n', '\n');
rendered = rendered.replaceAll('\r\n', '\n');

final sectionPattern = RegExp(r'# --- BEGIN USER: (\S+) ---\n(.*?)# --- END USER: \1 ---', dotAll: true);

// Extract user content from existing file
Expand Down
Loading
Loading