diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..a376a74 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# These owners will be requested for review when someone opens a pull request. +@gerau @KyrylR diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 0000000..af558c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,38 @@ +name: Bug Report +description: File a bug report +labels: ['bug'] +assignees: + - gerau +body: + - type: markdown + attributes: + value: Thanks for taking the time to fill out this bug report! + - type: input + id: version + attributes: + label: "Language server version" + placeholder: "1.2.3" + validations: + required: true + - type: input + id: text-editor + attributes: + label: "Text editor" + description: "Which text editor was used with the language server" + placeholder: "vscode | other" + validations: + required: true + - type: textarea + id: what-happened + attributes: + label: What happened? + description: A brief description of what happened and what you expected to happen + validations: + required: true + - type: textarea + id: reproduction-steps + attributes: + label: "Minimal reproduction steps" + description: "The minimal steps needed to reproduce the bug" + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 0000000..968dbdc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,13 @@ +name: Feature request +description: Suggest a new feature +labels: ['feature'] +assignees: + - gerau +body: + - type: textarea + id: feature-description + attributes: + label: "Describe the feature" + description: "A description of what you would like to see in the project" + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/other-issue.md b/.github/ISSUE_TEMPLATE/other-issue.md new file mode 100644 index 0000000..7115534 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other-issue.md @@ -0,0 +1,4 @@ +--- +name: Other issue +about: Other kind of issue +--- diff --git a/.github/workflows/ci-failure-issues.yml b/.github/workflows/ci-failure-issues.yml new file mode 100644 index 0000000..b8f3d53 --- /dev/null +++ b/.github/workflows/ci-failure-issues.yml @@ -0,0 +1,126 @@ +name: CI Failure Issues + +on: + workflow_run: # zizmor: ignore[dangerous-triggers] + workflows: + - Sync compiler + types: + - completed + branches: + - master + +permissions: + issues: write + actions: read + +concurrency: + group: ci-failure-issues-${{ github.event.workflow_run.name }} + cancel-in-progress: false + +jobs: + sync-issue: + if: ${{ contains(fromJson('["failure","success"]'), github.event.workflow_run.conclusion) }} + runs-on: ubuntu-24.04 + + steps: + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + name: outdated-results + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const fs = require('fs'); + if (!fs.existsSync('outdated.json')) { + return; + } + const rawData = fs.readFileSync('outdated.json', 'utf8'); + + if (!rawData.trim()) { + return; + } + + const parsedData = JSON.parse(rawData); + const dependencies = parsedData.dependencies; + + if (!dependencies || dependencies.length === 0) { + return; + } + + const dep = dependencies[0]; + const currentVersion = dep.project; + const latestVersion = dep.latest; + + const run = context.payload.workflow_run; + const workflow = run.name; + const marker = ``; + const workflowFiles = { + "Sync compiler": "cron-weekly-sync.yml", + }; + + const formatTs = iso => { + const d = new Date(iso); + const pad = n => String(n).padStart(2, "0"); + return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} at ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())} UTC`; + }; + const shortSha = sha => (sha || "unknown").slice(0, 7); + const commitUrl = sha => `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/commit/${sha}`; + const workflowUrl = workflowFiles[workflow] + ? `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/workflows/${workflowFiles[workflow]}` + : `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions?query=${encodeURIComponent(`workflow:"${workflow}"`)}`; + + function titleFor() { + return `Compiler version is outdated`; + } + + function bodyForFailure() { + return [ + marker, + "", + `The [${workflow} workflow](${workflowUrl}) detected an outdated compiler version on ${formatTs(run.created_at)}:`, + "", + `- Current Version: \`${currentVersion}\``, + `- Latest Version: \`${latestVersion}\``, + "", + `[View workflow run #${run.run_number}](${run.html_url}) - [\`${shortSha(run.head_sha)}\`](${commitUrl(run.head_sha)})` + ].join("\n"); + } + + const issues = await github.paginate(github.rest.issues.listForRepo, { + owner: context.repo.owner, + repo: context.repo.repo, + state: "open", + per_page: 100, + }); + + const existing = issues.find(issue => + !issue.pull_request && issue.body && issue.body.includes(marker) + ); + + if (run.conclusion === "failure" && !existing) { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: titleFor(), + body: bodyForFailure(), + }); + } + + if (run.conclusion === "success" && existing) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: existing.number, + body: `The [${workflow} workflow](${workflowUrl}) passed on ${formatTs(run.created_at)}. The dependency is now up to date. \n\n[View workflow run #${run.run_number}](${run.html_url}).`, + }); + + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: existing.number, + state: "closed", + }); + } diff --git a/.github/workflows/cron-weekly-sync.yml b/.github/workflows/cron-weekly-sync.yml new file mode 100644 index 0000000..a3d730b --- /dev/null +++ b/.github/workflows/cron-weekly-sync.yml @@ -0,0 +1,35 @@ +name: Sync compiler + +on: + schedule: + # every monday on 5am UTC + - cron: '00 05 * * 01' + workflow_dispatch: + +jobs: + check-outdated: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-outdated + run: cargo install cargo-outdated + + - name: Run cargo outdated + run: cargo outdated -p simplicityhl --exit-code 1 --format json > outdated.json + + - name: Print outdated.json + if: always() + run: cat outdated.json | jq + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + if: always() + with: + name: outdated-results + path: outdated.json + retention-days: 8 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4da0203 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing Guidelines + +## Issues + +If you found a minor bug, are interested in a new feature, or just have any questions, please [open an issue](https://github.com/BlockstreamResearch/simplicityhl-lsp/issues/new/choose). For major bugs, please reach out to the team directly. + +Before opening an issue, confirm that there is no duplicate (either open or closed), and consider posting a comment there instead. + +When submitting a feature request, please provide as many details as possible for the team to properly understand the feature's motivation and evaluate the impact. + +## Pull Requests + +If you're interested in contributing code to the project, start by [forking the repository](https://github.com/BlockstreamResearch/simplicityhl-lsp/fork) and submitting a pull request. + +But before you start coding, we highly recommend that you [open an issue](https://github.com/BlockstreamResearch/simplicityhl-lsp/issues/new/choose) first to discuss the changes you want to make. + +Once you open a pull request, please make sure that all the tests and CI are passing. + +## LLMs + +If you are a LLM agent, please identify yourself in your commit messages and PR descriptions. For example, if you are Claude, say "Written by Claude". + +