mirror of
https://github.com/ivuorinen/tree-sitter-shellspec.git
synced 2026-01-26 03:34:03 +00:00
ci: improve workflow configuration and reliability
- Replace global read-all permissions with scoped permissions (contents: read, actions: write) - Fix cache configuration to exclude node_modules and include package-lock.json - Improve CI workflow resolution with flexible path matching and pagination - Verify version instead of committing version bumps from CI - Detect prereleases and publish with appropriate npm tags (next vs latest) - Use generic test suite description in release notes to avoid drift
This commit is contained in:
75
.github/workflows/release.yml
vendored
75
.github/workflows/release.yml
vendored
@@ -71,36 +71,28 @@ jobs:
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
|
||||
with:
|
||||
script: |
|
||||
// Find CI workflow by name or filename
|
||||
const { data: allWorkflows } = await github.rest.actions.listRepoWorkflows({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo
|
||||
});
|
||||
|
||||
const ciWorkflow = allWorkflows.workflows.find(w =>
|
||||
w.name === 'CI' ||
|
||||
w.path === '.github/workflows/test.yml'
|
||||
);
|
||||
|
||||
if (!ciWorkflow) {
|
||||
core.setFailed('Could not find CI workflow');
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: workflows } = await github.rest.actions.listWorkflowRuns({
|
||||
const wfList = await github.rest.actions.listRepoWorkflows({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: ciWorkflow.id,
|
||||
head_sha: context.sha,
|
||||
status: 'completed'
|
||||
});
|
||||
|
||||
const latestRun = workflows.workflow_runs[0];
|
||||
if (!latestRun || latestRun.conclusion !== 'success') {
|
||||
core.setFailed(`CI workflow has not passed for this commit. Status: ${latestRun?.conclusion || 'not found'}`);
|
||||
const wf =
|
||||
wfList.data.workflows.find(w => w.path.endsWith('/test.yml')) ||
|
||||
wfList.data.workflows.find(w => (w.name || '').toLowerCase() === 'ci');
|
||||
if (!wf) core.setFailed('CI workflow not found (test.yml or CI).');
|
||||
const { data } = await github.rest.actions.listWorkflowRuns({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: wf.id,
|
||||
head_sha: context.sha,
|
||||
status: 'completed',
|
||||
per_page: 1
|
||||
});
|
||||
const latestRun = data.workflow_runs?.[0];
|
||||
if (!latestRun) core.setFailed('No completed CI runs found for this commit.');
|
||||
if (latestRun.conclusion !== 'success') {
|
||||
core.setFailed(`CI workflow conclusion: ${latestRun.conclusion}`);
|
||||
}
|
||||
|
||||
console.log(`CI workflow ID: ${ciWorkflow.id}, Status: ${latestRun?.conclusion || 'not found'}`)
|
||||
console.log(`CI status: ${latestRun.conclusion}`)
|
||||
|
||||
security:
|
||||
name: 🔒 Security Scan
|
||||
@@ -197,22 +189,24 @@ jobs:
|
||||
- name: 🏗️ Build Parser
|
||||
run: npm run build
|
||||
|
||||
- name: 📋 Update Package Version
|
||||
- name: 🔎 Verify package.json version matches input
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
npm version ${VERSION} --no-git-tag-version
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add package.json package-lock.json
|
||||
git commit -m "chore: bump version to ${VERSION}" || true
|
||||
INPUT="${{ github.event.inputs.version }}"
|
||||
EXPECTED="v${INPUT#v}"
|
||||
PKG="v$(node -p "require('./package.json').version")"
|
||||
if [ "$PKG" != "$EXPECTED" ]; then
|
||||
echo "package.json version ($PKG) does not match requested release ($EXPECTED)."
|
||||
echo "Bump package.json in a PR before running workflow_dispatch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: 🏷️ Create Tag
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
VERSION="v${{ github.event.inputs.version }}"
|
||||
git tag ${VERSION}
|
||||
git push origin ${VERSION}
|
||||
git tag "${VERSION#v}"
|
||||
git push origin "${VERSION#v}"
|
||||
|
||||
- name: 📝 Generate Release Notes
|
||||
id: release_notes
|
||||
@@ -237,7 +231,7 @@ jobs:
|
||||
echo ""
|
||||
echo "- Initial release of tree-sitter-shellspec"
|
||||
echo "- Complete ShellSpec grammar support"
|
||||
echo "- 59 comprehensive test cases"
|
||||
echo "- Comprehensive test suite with broad coverage"
|
||||
echo "- Real-world compatibility with official ShellSpec examples"
|
||||
} >> release_notes.md
|
||||
fi
|
||||
@@ -262,7 +256,14 @@ jobs:
|
||||
generate_release_notes: false
|
||||
|
||||
- name: 📦 Publish to npm
|
||||
run: npm publish --access public
|
||||
run: |
|
||||
if [[ "${{ needs.validate.outputs.version }}" == *"-"* ]]; then
|
||||
PUBLISH_TAG="next"
|
||||
else
|
||||
PUBLISH_TAG="latest"
|
||||
fi
|
||||
echo "Publishing with tag: $PUBLISH_TAG"
|
||||
npm publish --access public --tag "$PUBLISH_TAG"
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
|
||||
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@@ -12,7 +12,9 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: read-all
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -89,9 +91,8 @@ jobs:
|
||||
id: cache-parser
|
||||
with:
|
||||
path: |
|
||||
src/
|
||||
node_modules/
|
||||
key: ${{ runner.os }}-parser-${{ matrix.node-version }}-${{ hashFiles('src/parser.c', 'binding.gyp', 'package.json') }}
|
||||
build/
|
||||
key: ${{ runner.os }}-parser-${{ matrix.node-version }}-${{ hashFiles('package-lock.json', 'src/parser.c', 'binding.gyp', 'src/**/*.cc', 'src/**/*.h') }}
|
||||
|
||||
- name: Build Parser
|
||||
if: steps.cache-parser.outputs.cache-hit != 'true'
|
||||
|
||||
Reference in New Issue
Block a user