mirror of
https://github.com/ivuorinen/tree-sitter-shellspec.git
synced 2026-03-10 07:01:44 +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
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
// Find CI workflow by name or filename
|
const wfList = await github.rest.actions.listRepoWorkflows({
|
||||||
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({
|
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
workflow_id: ciWorkflow.id,
|
|
||||||
head_sha: context.sha,
|
|
||||||
status: 'completed'
|
|
||||||
});
|
});
|
||||||
|
const wf =
|
||||||
const latestRun = workflows.workflow_runs[0];
|
wfList.data.workflows.find(w => w.path.endsWith('/test.yml')) ||
|
||||||
if (!latestRun || latestRun.conclusion !== 'success') {
|
wfList.data.workflows.find(w => (w.name || '').toLowerCase() === 'ci');
|
||||||
core.setFailed(`CI workflow has not passed for this commit. Status: ${latestRun?.conclusion || 'not found'}`);
|
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 status: ${latestRun.conclusion}`)
|
||||||
console.log(`CI workflow ID: ${ciWorkflow.id}, Status: ${latestRun?.conclusion || 'not found'}`)
|
|
||||||
|
|
||||||
security:
|
security:
|
||||||
name: 🔒 Security Scan
|
name: 🔒 Security Scan
|
||||||
@@ -197,22 +189,24 @@ jobs:
|
|||||||
- name: 🏗️ Build Parser
|
- name: 🏗️ Build Parser
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: 📋 Update Package Version
|
- name: 🔎 Verify package.json version matches input
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ github.event.inputs.version }}"
|
INPUT="${{ github.event.inputs.version }}"
|
||||||
npm version ${VERSION} --no-git-tag-version
|
EXPECTED="v${INPUT#v}"
|
||||||
git config user.name "github-actions[bot]"
|
PKG="v$(node -p "require('./package.json').version")"
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
if [ "$PKG" != "$EXPECTED" ]; then
|
||||||
git add package.json package-lock.json
|
echo "package.json version ($PKG) does not match requested release ($EXPECTED)."
|
||||||
git commit -m "chore: bump version to ${VERSION}" || true
|
echo "Bump package.json in a PR before running workflow_dispatch."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: 🏷️ Create Tag
|
- name: 🏷️ Create Tag
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
run: |
|
run: |
|
||||||
VERSION="v${{ github.event.inputs.version }}"
|
VERSION="v${{ github.event.inputs.version }}"
|
||||||
git tag ${VERSION}
|
git tag "${VERSION#v}"
|
||||||
git push origin ${VERSION}
|
git push origin "${VERSION#v}"
|
||||||
|
|
||||||
- name: 📝 Generate Release Notes
|
- name: 📝 Generate Release Notes
|
||||||
id: release_notes
|
id: release_notes
|
||||||
@@ -237,7 +231,7 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
echo "- Initial release of tree-sitter-shellspec"
|
echo "- Initial release of tree-sitter-shellspec"
|
||||||
echo "- Complete ShellSpec grammar support"
|
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"
|
echo "- Real-world compatibility with official ShellSpec examples"
|
||||||
} >> release_notes.md
|
} >> release_notes.md
|
||||||
fi
|
fi
|
||||||
@@ -262,7 +256,14 @@ jobs:
|
|||||||
generate_release_notes: false
|
generate_release_notes: false
|
||||||
|
|
||||||
- name: 📦 Publish to npm
|
- 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:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
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 }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions: read-all
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
@@ -89,9 +91,8 @@ jobs:
|
|||||||
id: cache-parser
|
id: cache-parser
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
src/
|
build/
|
||||||
node_modules/
|
key: ${{ runner.os }}-parser-${{ matrix.node-version }}-${{ hashFiles('package-lock.json', 'src/parser.c', 'binding.gyp', 'src/**/*.cc', 'src/**/*.h') }}
|
||||||
key: ${{ runner.os }}-parser-${{ matrix.node-version }}-${{ hashFiles('src/parser.c', 'binding.gyp', 'package.json') }}
|
|
||||||
|
|
||||||
- name: Build Parser
|
- name: Build Parser
|
||||||
if: steps.cache-parser.outputs.cache-hit != 'true'
|
if: steps.cache-parser.outputs.cache-hit != 'true'
|
||||||
|
|||||||
Reference in New Issue
Block a user