feat(typescript-dev): ✨ switch to TypeScript native language server (TS 7 preview) #89
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Pull Request Validation | |
| on: | |
| pull_request: | |
| branches: [main] | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| conventional-commits: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| status: ${{ steps.status.outputs.status }} | |
| steps: | |
| - name: Check conventional commits | |
| uses: helpers4/action/conventional-commits@main | |
| with: | |
| checkout: "true" | |
| pr-comment: "error" | |
| - name: Set status | |
| id: status | |
| if: always() | |
| run: | | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "status=success" >> $GITHUB_OUTPUT | |
| else | |
| echo "status=failure" >> $GITHUB_OUTPUT | |
| fi | |
| test-features: | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - features: essential-dev | |
| baseImage: debian:latest | |
| - features: essential-dev | |
| baseImage: ubuntu:latest | |
| - features: essential-dev | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: helpers4-common,shell-history-per-project | |
| baseImage: debian:latest | |
| - features: helpers4-common,shell-history-per-project | |
| baseImage: ubuntu:latest | |
| - features: helpers4-common,shell-history-per-project | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: helpers4-common,git-absorb | |
| baseImage: debian:latest | |
| - features: helpers4-common,git-absorb | |
| baseImage: ubuntu:latest | |
| - features: helpers4-common,git-absorb | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: helpers4-common,angular-dev | |
| baseImage: mcr.microsoft.com/devcontainers/javascript-node:20 | |
| - features: helpers4-common,package-auto-install | |
| baseImage: mcr.microsoft.com/devcontainers/javascript-node:20 | |
| - features: helpers4-common | |
| baseImage: debian:latest | |
| - features: helpers4-common | |
| baseImage: ubuntu:latest | |
| - features: claude-dev | |
| baseImage: ubuntu:latest | |
| - features: helpers4-common,pnpm-store | |
| baseImage: mcr.microsoft.com/devcontainers/typescript-node:20 | |
| - features: helpers4-common,pnpm-store | |
| baseImage: ubuntu:latest | |
| - features: helpers4-common,vite-plus | |
| baseImage: mcr.microsoft.com/devcontainers/typescript-node:20 | |
| - features: typescript-dev | |
| baseImage: mcr.microsoft.com/devcontainers/typescript-node:20 | |
| - features: helpers4-common,auto-header | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: helpers4-common,peon-ping | |
| baseImage: ubuntu:latest | |
| - features: helpers4-common,peon-ping | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: dotfiles-sync | |
| baseImage: debian:latest | |
| - features: dotfiles-sync | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| - features: github-dev | |
| baseImage: mcr.microsoft.com/devcontainers/base:debian | |
| - features: github-dev | |
| baseImage: mcr.microsoft.com/devcontainers/base:ubuntu | |
| outputs: | |
| status: ${{ steps.status.outputs.status }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Install latest devcontainer CLI | |
| run: npm install -g @devcontainers/cli | |
| - name: Create mount sources for dotfiles-sync | |
| if: matrix.features == 'dotfiles-sync' | |
| # All bind sources declared in src/dotfiles-sync/devcontainer-feature.json | |
| # must exist on the host or `docker run` aborts before the test runs. | |
| run: | | |
| mkdir -p ~/.ssh ~/.gnupg \ | |
| ~/.config/git ~/.config/gh ~/.config/pnpm ~/.config/pip \ | |
| ~/.cargo ~/.aws ~/.kube ~/.docker | |
| touch ~/.gitconfig ~/.gitignore_global ~/.npmrc ~/.yarnrc.yml \ | |
| ~/.config/pnpm/rc ~/.config/gh/config.yml ~/.config/gh/hosts.yml \ | |
| ~/.cargo/config.toml ~/.config/pip/pip.conf \ | |
| ~/.aws/config ~/.kube/config ~/.docker/config.json | |
| - name: "Test feature '${{ matrix.features }}' against '${{ matrix.baseImage }}'" | |
| run: devcontainer features test --features ${{ matrix.features }} --base-image ${{ matrix.baseImage }} . | |
| shellcheck: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| status: ${{ steps.status.outputs.status }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Run ShellCheck on install scripts | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y shellcheck | |
| find src -name "install.sh" -exec shellcheck -S warning {} + | |
| - name: Set status | |
| id: status | |
| if: always() | |
| run: | | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "status=success" >> $GITHUB_OUTPUT | |
| else | |
| echo "status=failure" >> $GITHUB_OUTPUT | |
| fi | |
| pr-comment: | |
| runs-on: ubuntu-latest | |
| needs: [conventional-commits, test-features, shellcheck] | |
| if: always() | |
| steps: | |
| - name: Update PR comment | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const jobs = { | |
| '🧾 Conventional Commits': "${{ needs.conventional-commits.outputs.status || 'unknown' }}", | |
| '🧪 Feature Tests': "${{ needs.test-features.result || 'unknown' }}", | |
| '🐚 ShellCheck': "${{ needs.shellcheck.outputs.status || 'unknown' }}", | |
| }; | |
| const rows = Object.entries(jobs).map(([job, status]) => { | |
| const icon = status === 'success' ? '✅' : | |
| status === 'failure' ? '❌' : | |
| status === 'skipped' ? '⏭️' : '⚠️'; | |
| const badge = status === 'success' ? '`passing`' : | |
| status === 'failure' ? '`failing`' : | |
| status === 'skipped' ? '`skipped`' : '`unknown`'; | |
| return `| ${icon} | **${job}** | ${badge} |`; | |
| }).join('\n'); | |
| const passedCount = Object.values(jobs).filter(s => s === 'success').length; | |
| const totalJobs = Object.keys(jobs).length; | |
| const allPassed = passedCount === totalJobs; | |
| const statusBanner = allPassed | |
| ? '## ✅ PR Validation Passed\n\n> All checks passed!' | |
| : `## ❌ PR Validation Failed\n\n> ${passedCount}/${totalJobs} checks passed`; | |
| const comment = `${statusBanner} | |
| --- | |
| ### 📋 Pipeline Status | |
| | | Job | Status | | |
| |:---:|-----|:------:| | |
| ${rows} | |
| --- | |
| <sub>🤖 Generated by **@helpers4** CI • ${new Date().toISOString().split('T')[0]}</sub>`; | |
| try { | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const botComment = comments.find(c => | |
| c.user.type === 'Bot' && c.body.includes('PR Validation') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: comment | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: comment | |
| }); | |
| } | |
| } catch (error) { | |
| console.error('Error updating PR comment:', error); | |
| } |