From c5b23ad4c88b4a907fdb08fef34c058e21e46664 Mon Sep 17 00:00:00 2001 From: YoHanKi Date: Sun, 9 Aug 2026 00:02:06 +0900 Subject: [PATCH] =?UTF-8?q?EGC=5F013=20:=20=EB=A7=88=EC=BC=93=ED=94=8C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=8A=A4=20=EA=B2=8C=EC=8B=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=85=9D=EC=9D=84=20=EB=A6=B4=EB=A6=AC=EC=8A=A4=20=EC=9E=A1=20?= =?UTF-8?q?=EC=95=88=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20[skip=20rele?= =?UTF-8?q?ase]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.0.0 이 태그되고 GitHub 릴리스까지 만들어졌지만 첨부 파일이 없고 마켓플레이스에도 올라가지 않았다. release.yml 은 실행 이력이 0건이다. 원인은 GitHub Actions 의 루프 방지 규칙이다. GITHUB_TOKEN 으로 발생시킨 이벤트는 다른 워크플로를 트리거하지 않는다. release 잡이 gh release create 로 릴리스를 만들었지만 그 released 이벤트가 release.yml 을 깨우지 못했다. 파이프라인을 설계할 때 놓친 부분이다. ## 수정 서명·게시·자산 첨부를 build.yml 의 release 잡 안으로 옮겼다. 이벤트를 경유하지 않으므로 중간 단계가 사라지고, 방금 버전을 올린 그 잡이 그대로 빌드된 산출물을 게시한다. release.yml 은 지우지 않고 workflow_dispatch 로 바꿨다. 이미 태그는 있는데 게시되지 않은 상황을 복구하는 용도이며 - 지금의 2.0.0 이 정확히 그 상황이다 - 아무것도 삭제하지 않고 되살릴 수 있다. 태그와 pluginVersion 이 어긋나면 게시하지 않도록 확인 스텝을 뒀다. 커밋 메시지의 [skip release] 는 의도적이다. 이 변경으로 2.0.1 을 낼 이유가 없고, 2.0.0 을 먼저 마켓플레이스에 올려야 한다. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/build.yml | 17 +++++++++++ .github/workflows/release.yml | 54 ++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0d89866..292db34 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -284,3 +284,20 @@ jobs: --target main \ --title "${{ steps.version.outputs.next }}" \ --notes-file ./build/tmp/release_note.txt + + # Signing and publishing happen here rather than in a workflow listening for the `release` event. + # GitHub deliberately does not start workflows from events raised with GITHUB_TOKEN, so the release + # created above never woke anything up: 2.0.0 was tagged with no assets and never reached the + # Marketplace. Doing it in the same job removes the indirection entirely. + - name: Publish to JetBrains Marketplace + env: + PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} + CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }} + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }} + run: ./gradlew publishPlugin + + - name: Attach the plugin to the release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload "${{ steps.version.outputs.next }}" ./build/distributions/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8643af..6ed65e9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,21 +1,30 @@ -# GitHub Actions Workflow created for handling the release process based on the draft release prepared with the Build workflow. -# Running the publishPlugin task requires all the following secrets to be provided: PUBLISH_TOKEN, PRIVATE_KEY, PRIVATE_KEY_PASSWORD, CERTIFICATE_CHAIN. -# See https://plugins.jetbrains.com/docs/intellij/plugin-signing.html for more information. +# Manual publish of an existing tag to JetBrains Marketplace. +# +# The automated path lives in build.yml: its `release` job bumps the version, tags, and publishes in one +# go. This workflow is the escape hatch for a tag that exists but was never published - which is exactly +# how 2.0.0 ended up tagged with no assets, because GitHub does not start workflows from events raised +# with GITHUB_TOKEN, so the old `on: release` trigger here never fired. +# +# Requires the same secrets as the automated path: PUBLISH_TOKEN, CERTIFICATE_CHAIN, PRIVATE_KEY, +# PRIVATE_KEY_PASSWORD. + +name: Publish tag -name: Release on: - release: - types: [prereleased, released] + workflow_dispatch: + inputs: + tag: + description: 'Tag to publish, e.g. 2.0.0' + required: true + type: string jobs: - # Prepare and publish the plugin to JetBrains Marketplace repository - release: - name: Publish Plugin + publish: + name: Publish to Marketplace runs-on: ubuntu-latest permissions: contents: write - pull-requests: write steps: # Free GitHub Actions Environment Disk Space @@ -25,30 +34,30 @@ jobs: tool-cache: false large-packages: false - # Check out the current repository - name: Fetch Sources uses: actions/checkout@v5 with: - ref: ${{ github.event.release.tag_name }} + ref: ${{ inputs.tag }} - # Set up the Java environment for the next steps - name: Setup Java uses: actions/setup-java@v5 with: distribution: zulu java-version: 21 - # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v5 - with: - cache-read-only: true - # No changelog step here. The release job in build.yml patches and commits CHANGELOG.md before the - # release is created, so doing it again would duplicate the section - and the pull request this - # workflow used to open to carry that edit back is no longer needed either. + # Guards against publishing a build that does not match the tag it claims to be. + - name: Check the tag matches pluginVersion + run: | + VERSION=$(grep -E '^[[:space:]]*pluginVersion' gradle.properties | sed 's/^[^=]*=//' | tr -d '[:space:]') + if [ "$VERSION" != "${{ inputs.tag }}" ]; then + echo "Tag '${{ inputs.tag }}' does not match pluginVersion '$VERSION'" + exit 1 + fi + echo "Publishing $VERSION" - # Publish the plugin to JetBrains Marketplace - name: Publish Plugin env: PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} @@ -57,8 +66,7 @@ jobs: PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }} run: ./gradlew publishPlugin - # Upload an artifact as a release asset - - name: Upload Release Asset + - name: Attach the plugin to the release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/* + run: gh release upload "${{ inputs.tag }}" ./build/distributions/* --clobber