Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .buildkite/pipeline.qodana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Qodana code quality pipeline — replaces .github/workflows/qodana_code_quality.yml
# Triggered on pushes to main/releases/* and on pull requests.
# Skips documentation-only changes (CHANGELOG.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, README.md, img/**).

steps:
- label: ":qodana: Qodana Scan"
key: qodana
agents:
queue: default
env:
QODANA_TOKEN: $${QODANA_TOKEN?}
QODANA_ENDPOINT: "https://qodana.cloud"
Comment on lines +10 to +12
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Buildkite pipeline YAML env variable interpolation escaped dollar signs in env blocks

💡 Result:

In Buildkite pipeline YAML files, particularly when using buildkite-agent pipeline upload, environment variable interpolation occurs using $VAR or ${VAR} syntax. To prevent interpolation during upload (so the variable is evaluated at runtime instead), escape the dollar sign with $$ or $ in commands, env blocks, or other strings. Example from official docs: - command: "deploy.sh $$SERVER" env: SERVER: "server-a" Here, $$SERVER becomes $SERVER at runtime, allowing the job's environment to interpolate it. This applies to env blocks in steps. Top-level env in pipeline.yml sets variables for subsequent steps and is available for interpolation in further uploads. For literal dollars without interpolation, use $$ or $. Use --no-interpolation flag on pipeline upload to disable entirely (agent v3.1.1+). Sources confirm this behavior consistently across docs and GitHub issues.

Citations:


Do not escape QODANA_TOKEN with double dollar signs in the env: block.

Using $${QODANA_TOKEN?} prevents Buildkite's upload-time interpolation, leaving ${QODANA_TOKEN?} as a literal environment variable value that Docker receives instead of the actual token. Either use unescaped ${QODANA_TOKEN?} to interpolate the secret during pipeline upload, or configure the token to be injected at runtime through Buildkite's agent secrets mechanism.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.qodana.yml around lines 10 - 12, The pipeline currently
escapes QODANA_TOKEN as $${QODANA_TOKEN?} which prevents Buildkite from
interpolating the secret at upload time; change the env entry to use unescaped
${QODANA_TOKEN?} so Buildkite will substitute the actual token during pipeline
upload (or alternatively remove the env entry and configure QODANA_TOKEN to be
injected at runtime via Buildkite agent secrets); update the env block
referencing QODANA_TOKEN (and keep QODANA_ENDPOINT as-is) to apply the fix.

commands:
- |
# Skip if all changed files are documentation-only
CHANGED="$$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only origin/main...HEAD)"
NON_DOC="$$(echo "$$CHANGED" | grep -vE '^(CHANGELOG|CONTRIBUTING|CODE_OF_CONDUCT|README)\.md$$' | grep -v '^img/')"
if [ -z "$$NON_DOC" ]; then
Comment on lines +16 to +18
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Diff the full PR range before deciding to skip Qodana.

HEAD~1 HEAD only inspects the last commit, so a PR with source changes followed by a docs-only commit can incorrectly skip the scan. Also make the grep filter tolerant of “no non-doc files” under errexit.

Proposed fix
-        CHANGED="$$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only origin/main...HEAD)"
-        NON_DOC="$$(echo "$$CHANGED" | grep -vE '^(CHANGELOG|CONTRIBUTING|CODE_OF_CONDUCT|README)\.md$$' | grep -v '^img/')"
+        if [ "$${BUILDKITE_PULL_REQUEST:-false}" != "false" ]; then
+          CHANGED="$$(git diff --name-only origin/main...HEAD)"
+        else
+          CHANGED="$$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only origin/main...HEAD)"
+        fi
+        NON_DOC="$$(echo "$$CHANGED" | grep -vE '^(CHANGELOG|CONTRIBUTING|CODE_OF_CONDUCT|README)\.md$$' | grep -v '^img/' || true)"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.qodana.yml around lines 16 - 18, Update the CHANGED
assignment to diff the full PR range instead of only the last commit by using
git diff --name-only origin/main...HEAD (fetch origin/main first and fallback to
HEAD~1 HEAD only if necessary) and make the NON_DOC pipeline tolerant of no
matches by appending "|| true" to the grep commands; specifically modify the
CHANGED variable and the NON_DOC pipeline (the lines that set CHANGED and
NON_DOC) so CHANGED is populated from origin/main...HEAD and NON_DOC uses "grep
-vE '^(CHANGELOG|CONTRIBUTING|CODE_OF_CONDUCT|README)\.md$' | grep -v '^img/' ||
true" to avoid failing under errexit when there are no non-doc files, leaving
the subsequent if [ -z "$NON_DOC" ] check unchanged.

echo "Only documentation changes detected — skipping Qodana scan."
exit 0
fi
- |
# Run Qodana via Docker (mirrors the JetBrains/qodana-action behavior)
docker run --rm \
-v "$$(pwd):/data/project" \
-e QODANA_TOKEN="$$QODANA_TOKEN" \
-e QODANA_ENDPOINT="$$QODANA_ENDPOINT" \
jetbrains/qodana-jvm:2025.3 \
--save-report \
--results-dir /data/project/build/qodana/results \
--report-dir /data/project/build/qodana/report
artifact_paths:
- "build/qodana/report/**/*"
59 changes: 59 additions & 0 deletions .buildkite/pipeline.release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Release pipeline — replaces .github/workflows/release.yml

steps:
- label: ":rocket: Publish Plugin"
key: publish
env:
PUBLISH_TOKEN: $${PUBLISH_TOKEN?}
CERTIFICATE_CHAIN: $${CERTIFICATE_CHAIN?}
PRIVATE_KEY: $${PRIVATE_KEY?}
PRIVATE_KEY_PASSWORD: $${PRIVATE_KEY_PASSWORD?}
GITHUB_TOKEN: $${GITHUB_TOKEN?}
plugins:
- docker#v5.12.0:
image: "gradle:8-jdk21"
environment:
- PUBLISH_TOKEN
- CERTIFICATE_CHAIN
- PRIVATE_KEY
- PRIVATE_KEY_PASSWORD
commands:
Comment on lines +6 to +20
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Checks whether the release container image has GitHub CLI available.
docker run --rm --entrypoint sh gradle:8-jdk21 -lc 'command -v gh && gh --version'

Repository: z8dn/advanced-android-project-view

Length of output: 124


🏁 Script executed:

cat -n .buildkite/pipeline.release.yml

Repository: z8dn/advanced-android-project-view

Length of output: 2321


🏁 Script executed:

# Search for uses of gh command and GITHUB_TOKEN in the codebase
rg 'gh ' --type yaml
rg 'GITHUB_TOKEN' --type yaml

Repository: z8dn/advanced-android-project-view

Length of output: 60


🏁 Script executed:

# Check if there are other buildkite pipeline files or docs
fd 'pipeline' --type f

Repository: z8dn/advanced-android-project-view

Length of output: 60


🏁 Script executed:

# Look for Dockerfile, docker-compose, or other Docker configs
fd -e Dockerfile -e dockerfile
fd -e 'docker-compose*'

Repository: z8dn/advanced-android-project-view

Length of output: 60


🏁 Script executed:

# Check if there are any scripts that set up the environment
fd -e 'sh' -e 'bash' | head -20

Repository: z8dn/advanced-android-project-view

Length of output: 60


🏁 Script executed:

# Search for any setup steps or gh installation references
rg 'gh ' -A 2 -B 2 --type yaml --type sh
rg 'docker' .buildkite/ -i

Repository: z8dn/advanced-android-project-view

Length of output: 444


Add GITHUB_TOKEN to Docker container environment and ensure GitHub CLI is available in the release image.

The GITHUB_TOKEN variable is defined in env (line 11) but is not included in the Docker plugin's environment list (lines 15-19). The commands on lines 25, 36, 47, and 51 call gh (GitHub CLI), which neither exists in gradle:8-jdk21 nor will authenticate without the token. The release step will fail with "command not found" or authentication errors.

Add GITHUB_TOKEN to the Docker plugin environment and switch to an image that includes both Gradle 8, JDK 21, and GitHub CLI, or install gh in the container entrypoint.

Proposed fix
     plugins:
       - docker#v5.12.0:
-          image: "gradle:8-jdk21"
+          image: "<image-with-gradle-jdk21-and-gh>"
           environment:
             - PUBLISH_TOKEN
             - CERTIFICATE_CHAIN
             - PRIVATE_KEY
             - PRIVATE_KEY_PASSWORD
+            - GITHUB_TOKEN
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.release.yml around lines 6 - 20, The Docker plugin block
fails to pass GITHUB_TOKEN into the container and the chosen image
(gradle:8-jdk21) does not include the GitHub CLI, causing gh commands to be
missing or unauthenticated; update the docker plugin configuration used in the
pipeline (the docker#v5.12.0 plugin block) to add GITHUB_TOKEN to the
environment list and either switch the image to one that bundles Gradle 8 + JDK
21 + gh or add an install step that installs GitHub CLI (so gh is available)
before any commands that call gh; ensure the environment entry name exactly
matches GITHUB_TOKEN and that subsequent commands rely on that token for
authentication.

- |
TAG="$$BUILDKITE_TAG"

if [ -z "$$RELEASE_BODY" ]; then
RELEASE_BODY="$$(gh release view "$$TAG" --json body -q '.body')"
Comment on lines +21 to +25
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fail fast when the release pipeline is not running for a tag.

TAG can be empty outside tag builds, which makes the following gh release view/upload calls operate with an invalid release identifier.

Proposed fix
-        TAG="$$BUILDKITE_TAG"
+        TAG="$${BUILDKITE_TAG:?Release pipeline must run on a tag build}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- |
TAG="$$BUILDKITE_TAG"
if [ -z "$$RELEASE_BODY" ]; then
RELEASE_BODY="$$(gh release view "$$TAG" --json body -q '.body')"
- |
TAG="$${BUILDKITE_TAG:?Release pipeline must run on a tag build}"
if [ -z "$$RELEASE_BODY" ]; then
RELEASE_BODY="$$(gh release view "$$TAG" --json body -q '.body')"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.release.yml around lines 21 - 25, The pipeline currently
assumes TAG is set and will run gh release view/upload with an empty identifier;
add a guard right after the TAG="$$BUILDKITE_TAG" assignment to fail fast if TAG
is empty (e.g., check [ -z "$$TAG" ]) and exit with a non-zero status and clear
error message, before any usage of RELEASE_BODY or calls to gh release view / gh
release upload so the script never calls gh with an invalid release identifier.

fi

CHANGELOG="$$(echo "$$RELEASE_BODY" | sed -e 's/^[[:space:]]*$$//g' -e '/./,$$!d')"

if [ -n "$$CHANGELOG" ]; then
gradle patchChangelog --release-note="$$CHANGELOG"
fi

gradle publishPlugin

gh release upload "$$TAG" ./build/distributions/*
Comment on lines +30 to +36
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify release pipeline Gradle invocations against the wrapper version.
set -euo pipefail

echo "Wrapper Gradle distribution:"
fd -a 'gradle-wrapper.properties' . | xargs -r sed -n '1,20p'

echo
echo "Buildkite Gradle invocations:"
rg -n -C2 '\bgradle\b|\.\/gradlew|gradlew\.bat' --glob '.buildkite/*.yml'

Repository: z8dn/advanced-android-project-view

Length of output: 521


🏁 Script executed:

#!/bin/bash
# Fix: Use proper escaping for rg regex pattern
set -euo pipefail

echo "Checking .buildkite/pipeline.release.yml around lines 30-36:"
head -40 .buildkite/pipeline.release.yml | tail -15

echo
echo "Searching for gradle invocations in .buildkite/ directory:"
rg 'gradle|gradlew' '.buildkite/' -n

Repository: z8dn/advanced-android-project-view

Length of output: 1860


Use ./gradlew so release uses the checked-in wrapper.

The release pipeline currently runs gradle from the container image (gradle:8-jdk21), while the repository wrapper is pinned to Gradle 9.4.1. This version mismatch can cause release-only Gradle behavior to diverge from the main build.

Lines 31 and 34 in .buildkite/pipeline.release.yml need to be updated to use ./gradlew:

  • Line 31: gradle patchChangelog./gradlew patchChangelog
  • Line 34: gradle publishPlugin./gradlew publishPlugin
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.release.yml around lines 30 - 36, The pipeline invokes
the container's Gradle binary which can mismatch the repo wrapper; update the
two Gradle invocations to use the checked-in wrapper by replacing the command
strings that call "gradle patchChangelog --release-note=..." and "gradle
publishPlugin" with "./gradlew patchChangelog --release-note=..." and "./gradlew
publishPlugin" respectively so the release job runs with the pinned Gradle
wrapper version.


if [ -n "$$CHANGELOG" ]; then
BRANCH="changelog-update-$$TAG"

git config user.email "buildkite@ci"
git config user.name "Buildkite"
git checkout -b "$$BRANCH"
git commit -am "Changelog update - $$TAG"
git push --set-upstream origin "$$BRANCH"

gh label create "release changelog" \
--description "Pull requests with release changelog update" \
--force || true

gh pr create \
--title "Changelog update - \`$$TAG\`" \
--body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$$TAG\` version." \
--label "release changelog" \
--head "$$BRANCH"
fi

artifact_paths:
- "build/distributions/*.zip"
74 changes: 74 additions & 0 deletions .buildkite/pipeline.ui-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# UI test pipeline — replaces .github/workflows/run-ui-tests.yml
# Triggered manually via `buildkite-agent pipeline upload .buildkite/pipeline.ui-tests.yml`
# or by triggering the pipeline from the Buildkite UI.

steps:
# ─── Linux ────────────────────────────────────────────────────────────────
- label: ":linux: UI Tests (Linux)"
key: ui-test-linux
agents:
os: linux
queue: default
env:
JAVA_HOME: /usr/lib/jvm/zulu-21-amd64
DISPLAY: ":99.0"
commands:
- Xvfb -ac :99 -screen 0 1920x1080x16 &
- ./gradlew runIdeForUiTests &
- |
# Wait for IDE to be ready (equivalent to url-health-check-action)
for i in $$(seq 1 15); do
if curl -sf http://127.0.0.1:8082 > /dev/null 2>&1; then
echo "IDE is ready"
break
fi
echo "Attempt $$i/15 — waiting 30s..."
sleep 30
done
- ./gradlew test
Comment on lines +18 to +28
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fail the UI step when the IDE never becomes ready.

All three readiness loops fall through after 15 failed attempts and still run tests. Add an explicit timeout failure before invoking test.

Proposed fix
         # Wait for IDE to be ready (equivalent to url-health-check-action)
+        READY=0
         for i in $$(seq 1 15); do
           if curl -sf http://127.0.0.1:8082 > /dev/null 2>&1; then
             echo "IDE is ready"
+            READY=1
             break
           fi
           echo "Attempt $$i/15 — waiting 30s..."
           sleep 30
         done
+        if [ "$$READY" -ne 1 ]; then
+          echo "IDE did not become ready after 15 attempts"
+          exit 1
+        fi

Apply the same READY guard to the macOS block, and for Windows:

         for /L %%i in (1,1,15) do (
           curl -sf http://127.0.0.1:8082 >nul 2>&1 && (echo IDE is ready & goto :ready)
           echo Attempt %%i/15 - waiting 30s...
           timeout /t 30 /nobreak >nul
         )
+        echo IDE did not become ready after 15 attempts
+        exit /b 1
         :ready

Also applies to: 42-51, 65-72

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.ui-tests.yml around lines 18 - 28, The readiness loops
currently fall through and always run ./gradlew test even when the IDE never
becomes ready; introduce a READY guard: initialize READY=false before each loop,
set READY=true inside the curl success branch (where it currently echoes "IDE is
ready" and breaks), and after the loop check READY and if still false exit with
a non-zero status (e.g., exit 1) before invoking ./gradlew test; apply this same
READY pattern to the macOS and Windows blocks that contain the for i in $(seq
...) / curl checks and the subsequent ./gradlew test invocation.

artifact_paths:
- "build/reports/tests/**/*"

# ─── macOS ────────────────────────────────────────────────────────────────
- label: ":mac: UI Tests (macOS)"
key: ui-test-macos
agents:
os: macos
queue: default
env:
JAVA_HOME: /Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home
commands:
- ./gradlew runIdeForUiTests &
- |
for i in $$(seq 1 15); do
if curl -sf http://127.0.0.1:8082 > /dev/null 2>&1; then
echo "IDE is ready"
break
fi
echo "Attempt $$i/15 — waiting 30s..."
sleep 30
done
- ./gradlew test
artifact_paths:
- "build/reports/tests/**/*"

# ─── Windows ──────────────────────────────────────────────────────────────
- label: ":windows: UI Tests (Windows)"
key: ui-test-windows
agents:
os: windows
queue: default
env:
JAVA_HOME: "C:\\Program Files\\Zulu\\zulu-21"
commands:
- start gradlew.bat runIdeForUiTests
- |
for /L %%i in (1,1,15) do (
curl -sf http://127.0.0.1:8082 >nul 2>&1 && (echo IDE is ready & goto :ready)
echo Attempt %%i/15 - waiting 30s...
timeout /t 30 /nobreak >nul
)
:ready
- gradlew.bat test
artifact_paths:
- "build/reports/tests/**/*"
56 changes: 56 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Main CI pipeline — replaces .github/workflows/build.yml

steps:
- label: ":test_tube: Test"
key: test
command: "gradle check"
plugins:
- docker#v5.12.0:
image: "gradle:9-jdk21"
artifact_paths:
- "build/reports/tests/**/*"
- "build/reports/kover/report.xml"

- label: ":hammer: Build"
key: build
# buildSearchableOptions launches a full IntelliJ IDE process and requires ~4GB RAM.
# Skip it in CI; it only generates marketplace search indexes.
command: "gradle buildPlugin -x buildSearchableOptions"
plugins:
- docker#v5.12.0:
image: "gradle:9-jdk21"
artifact_paths:
- "build/distributions/*.zip"

- label: ":shield: Verify Plugin"
key: verify
command: "gradle verifyPlugin -x buildSearchableOptions --no-daemon --max-workers 1"
plugins:
- docker#v5.12.0:
image: "gradle:9-jdk21"
artifact_paths:
- "build/reports/pluginVerifier/**/*"

- wait: ~

- label: ":github: Create Release Draft"
key: release-draft
branches: "main"
agents:
queue: default
env:
GITHUB_TOKEN: $${GITHUB_TOKEN?}
commands:
- |
PROPERTIES="$$(gradle properties --console=plain -q)"
VERSION="$$(echo "$$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
CHANGELOG="$$(gradle getChangelog --unreleased --no-header --console=plain -q)"
Comment on lines +41 to +47
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .buildkite/pipeline.yml

Repository: z8dn/advanced-android-project-view

Length of output: 2177


🏁 Script executed:

fd -type f gradle-wrapper

Repository: z8dn/advanced-android-project-view

Length of output: 248


🌐 Web query:

Buildkite YAML env block $$ escaping interpolation environment variables

💡 Result:

In Buildkite pipeline YAML, particularly within env blocks, use $$ to escape the $ character for runtime environment variable interpolation. This prevents premature substitution during pipeline upload and allows the variable to be evaluated when the agent runs the step. For example: - command: "deploy.sh $$SERVER" env: SERVER: "server-a" Here, $$SERVER becomes $SERVER at runtime, so the shell expands SERVER. Both $$ and $ work for escaping. This applies to commands, triggers, and env values needing runtime evaluation. Official docs confirm: escape $ with $$ or $ for runtime vars (sources 3,5,8,9). Pipeline upload interpolates ${VAR} immediately unless escaped (source 5). For secrets, $$ also prevents exposure during upload (source 10).

Citations:


🏁 Script executed:

find . -name "gradlew*" -o -name "gradle-wrapper*" 2>/dev/null

Repository: z8dn/advanced-android-project-view

Length of output: 180


🏁 Script executed:

git ls-files | grep -i gradle

Repository: z8dn/advanced-android-project-view

Length of output: 363


Use ./gradlew instead of gradle on the default agent.

This step runs on the default agent (line 40: queue: default), not the Gradle Docker image. The gradle commands on lines 45 and 47 will fail if the agent does not have Gradle installed. The repository includes a Gradle wrapper (./gradlew), which should be used instead.

The GITHUB_TOKEN escaping at line 42 is already correct: $${GITHUB_TOKEN?} uses double-$ to prevent substitution during pipeline upload and allow runtime shell evaluation. Do not change this.

Proposed fix
     env:
       GITHUB_TOKEN: $${GITHUB_TOKEN?}
     commands:
       - |
-        PROPERTIES="$$(gradle properties --console=plain -q)"
+        PROPERTIES="$$(./gradlew properties --console=plain -q)"
          VERSION="$$(echo "$$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
-        CHANGELOG="$$(gradle getChangelog --unreleased --no-header --console=plain -q)"
+        CHANGELOG="$$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
env:
GITHUB_TOKEN: $${GITHUB_TOKEN?}
commands:
- |
PROPERTIES="$$(gradle properties --console=plain -q)"
VERSION="$$(echo "$$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
CHANGELOG="$$(gradle getChangelog --unreleased --no-header --console=plain -q)"
env:
GITHUB_TOKEN: $${GITHUB_TOKEN?}
commands:
- |
PROPERTIES="$$(./gradlew properties --console=plain -q)"
VERSION="$$(echo "$$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
CHANGELOG="$$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.yml around lines 41 - 47, The pipeline uses the system
gradle binary but runs on the default agent without Gradle; update the shell
commands that call gradle (the ones that populate PROPERTIES, VERSION, and
CHANGELOG) to invoke the repository Gradle wrapper instead by replacing calls to
"gradle" with "./gradlew" so the commands use ./gradlew properties and ./gradlew
getChangelog.


gh api repos/{owner}/{repo}/releases \
--jq '.[] | select(.draft == true) | .id' \
| xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}
Comment on lines +49 to +51
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Lists the draft releases the current command would delete.
gh api repos/{owner}/{repo}/releases \
  --jq '.[] | select(.draft == true) | [.id, .tag_name, .name] | `@tsv`'

Repository: z8dn/advanced-android-project-view

Length of output: 101


🏁 Script executed:

cat -n .buildkite/pipeline.yml | sed -n '40,60p'

Repository: z8dn/advanced-android-project-view

Length of output: 822


Limit draft deletion to the release tag being regenerated.

This deletes every draft release in the repository (line 49-51) before creating v$$VERSION. Any other manual draft releases in the repository would be silently removed, causing data loss. This is particularly risky in CI where it could destroy unrelated draft releases created by other processes or developers.

Safer tag-scoped deletion
-        gh api repos/{owner}/{repo}/releases \
-          --jq '.[] | select(.draft == true) | .id' \
-          | xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}
+        DRAFT_ID="$$(gh api repos/{owner}/{repo}/releases \
+          --jq ".[] | select(.draft == true and .tag_name == \"v$$VERSION\") | .id")"
+        if [ -n "$$DRAFT_ID" ]; then
+          gh api -X DELETE "repos/{owner}/{repo}/releases/$$DRAFT_ID"
+        fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
gh api repos/{owner}/{repo}/releases \
--jq '.[] | select(.draft == true) | .id' \
| xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}
DRAFT_ID="$$(gh api repos/{owner}/{repo}/releases \
--jq ".[] | select(.draft == true and .tag_name == \"v$$VERSION\") | .id")"
if [ -n "$$DRAFT_ID" ]; then
gh api -X DELETE "repos/{owner}/{repo}/releases/$$DRAFT_ID"
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.buildkite/pipeline.yml around lines 49 - 51, The current pipeline command
uses "gh api repos/{owner}/{repo}/releases" piped to "select(.draft == true) |
.id" and xargs DELETE which removes all draft releases; change it to only delete
the draft whose tag matches the release being regenerated (v$$VERSION) by
filtering releases for both .draft == true and .tag_name == "v$VERSION" before
extracting .id, and then DELETE only that ID (keep the same gh api ... DELETE
flow but narrow the jq filter to include tag_name == "v$VERSION" so unrelated
drafts are not removed).


gh release create "v$$VERSION" \
--draft \
--title "v$$VERSION" \
--notes "$$CHANGELOG"
5 changes: 1 addition & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ intellijPlatform {
}

pluginVerification {
freeArgs = listOf("-Xmx1g")
ides {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion"))
}
Expand All @@ -129,10 +130,6 @@ changelog {
}

tasks {
wrapper {
gradleVersion = providers.gradleProperty("gradleVersion").get()
}

publishPlugin {
dependsOn(patchChangelog)
}
Expand Down
4 changes: 1 addition & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pluginSinceBuild = 261

# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
# Android Studio Quail 1 | 2026.1.1 Canary 1 (Released Apr 16, 2026)
platformType = AI
platformVersion = 2026.1.1.1

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
Expand All @@ -19,9 +20,6 @@ platformPlugins =
# Example: platformBundledPlugins = com.intellij.java
platformBundledPlugins = org.jetbrains.plugins.gradle,com.intellij.java,org.jetbrains.android

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 8.14.3

# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
kotlin.stdlib.default.dependency = false

Expand Down
Loading