diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab14353..365c93c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,7 @@ permissions: contents: write # required for GitHub Release id-token: write # required for PyPI Trusted Publishing actions: write # required for tag deletion + discussions: write # attach the release-linked repo Discussion (Announcements) jobs: release: @@ -131,9 +132,43 @@ jobs: release-assets/* body_path: ${{ runner.temp }}/RELEASE_BODY.md generate_release_notes: true # appends categorized "What's Changed" (see .github/release.yml) + # Auto-open a repo-level Discussion linked to this release, seeded with + # the same notes. Requires Discussions enabled and this category to exist. + discussion_category_name: Announcements env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Mirror the release announcement into the ORG-level discussions, which are + # backed by codellm-devkit/.github. GITHUB_TOKEN can't write cross-repo, so + # this uses a PAT (ORG_DISCUSSIONS_TOKEN) with repo scope, and posts via the + # createDiscussion GraphQL mutation. Reuses the already-composed RELEASE_BODY.md + # so org and repo posts stay identical. + - name: Announce in org-level discussions (codellm-devkit/.github) + if: startsWith(github.ref, 'refs/tags/') + continue-on-error: true # a failed org post must not fail an otherwise-good release + env: + GH_TOKEN: ${{ secrets.ORG_DISCUSSIONS_TOKEN }} + VERSION: ${{ steps.tag_name.outputs.current_version }} + run: | + set -uo pipefail + OWNER="codellm-devkit"; REPO=".github"; CATEGORY="Announcements" + # The mutation needs GraphQL node IDs, not names — resolve them first. + RESP=$(gh api graphql \ + -f query='query($o:String!,$r:String!){repository(owner:$o,name:$r){id discussionCategories(first:25){nodes{id name}}}}' \ + -f o="$OWNER" -f r="$REPO") \ + || { echo "::warning::org discussion lookup failed — skipping org announcement."; exit 0; } + REPO_ID=$(echo "$RESP" | jq -r '.data.repository.id') + CAT_ID=$(echo "$RESP" | jq -r --arg c "$CATEGORY" '.data.repository.discussionCategories.nodes[]|select(.name==$c)|.id') + if [[ -z "$REPO_ID" || "$REPO_ID" == "null" || -z "$CAT_ID" ]]; then + echo "::warning::could not resolve $OWNER/$REPO discussion category '$CATEGORY' — skipping org announcement." + exit 0 + fi + gh api graphql \ + -f query='mutation($rid:ID!,$cid:ID!,$t:String!,$b:String!){createDiscussion(input:{repositoryId:$rid,categoryId:$cid,title:$t,body:$b}){discussion{url}}}' \ + -f rid="$REPO_ID" -f cid="$CAT_ID" \ + -f t="codeanalyzer-python v$VERSION" \ + -f b="$(cat "$RUNNER_TEMP/RELEASE_BODY.md")" + - name: Publish to PyPI via Trusted Publishing run: uv publish diff --git a/pyproject.toml b/pyproject.toml index 332748c..d938f2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "codeanalyzer-python" -version = "0.3.0" +version = "0.3.1" description = "Static Analysis on Python source code using Jedi, CodeQL and Treesitter — emits analysis.json or a Neo4j property graph." readme = "README.md" authors = [