Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

chore: add JetBrains auto-approval compliance linter#139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
blink-so wants to merge1 commit intomain
base:main
Choose a base branch
Loading
fromfeat/jetbrains-compliance-linter
Open
Show file tree
Hide file tree
Changes fromall 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
59 changes: 59 additions & 0 deletions.github/workflows/jetbrains-compliance.yml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
name: JetBrains Auto-Approval Compliance

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
compliance-check:
runs-on: ubuntu-latest
name: JetBrains Compliance Linting

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Make scripts executable
run: chmod +x ./scripts/jetbrains-compliance-check.sh

- name: Run JetBrains Compliance Checks
run: |
echo "Running JetBrains auto-approval compliance checks..."
./scripts/jetbrains-compliance-check.sh

- name: Comment PR with compliance status
if: github.event_name == 'pull_request' && failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '⚠️ **JetBrains Auto-Approval Compliance Check Failed**\n\n' +
'This PR contains code that violates JetBrains auto-approval requirements:\n\n' +
'- ❌ Do **not** use forbidden Kotlin experimental APIs\n' +
'- ❌ Do **not** add lambdas, handlers, or class handles to Java runtime hooks\n' +
'- ❌ Do **not** create threads manually (use coroutines or ensure cleanup in `CoderRemoteProvider#close()`)\n' +
'- ❌ Do **not** bundle libraries already provided by Toolbox\n' +
'- ❌ Do **not** perform ill-intentioned actions\n\n' +
'Please check the workflow logs for detailed violations and fix them before merging.'
})
97 changes: 97 additions & 0 deletionsJETBRAINS_COMPLIANCE.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
# JetBrains Auto-Approval Compliance

This document describes the linting setup to ensure compliance with JetBrains auto-approval requirements for Toolbox plugins.

## Overview

JetBrains has enabled auto-approval for this plugin, which requires following specific guidelines to maintain the approval status. This repository includes automated checks to ensure compliance.

## Requirements

Based on communication with JetBrains team, the following requirements must be met:

### ✅ Allowed
- **Coroutines**: Use `coroutineScope.launch` for concurrent operations
- **Library-managed threads**: Libraries like OkHttp with their own thread pools are acceptable
- **Some experimental coroutines APIs**: `kotlinx.coroutines.selects.select` and `kotlinx.coroutines.selects.onTimeout` are acceptable
- **Proper cleanup**: Ensure resources are released in `CoderRemoteProvider#close()` method

### ❌ Forbidden
- **Kotlin experimental APIs**: Core Kotlin experimental APIs (not coroutines-specific ones)
- **Java runtime hooks**: No lambdas, handlers, or class handles to Java runtime hooks
- **Manual thread creation**: Avoid `Thread()`, `Executors.new*()`, `ThreadPoolExecutor`, etc.
- **Bundled libraries**: Don't bundle libraries already provided by Toolbox
- **Ill-intentioned actions**: No malicious or harmful code

## Linting Setup

### JetBrains Compliance Check Script

The primary compliance checking is done via a shell script:

```bash
./scripts/jetbrains-compliance-check.sh
```

This script checks for:
- Forbidden experimental API usage
- Manual thread creation patterns
- Java runtime hooks
- Potentially bundled libraries
- Coroutines best practices

### Standard Code Quality (Detekt)

Standard Kotlin code quality is checked using Detekt:

```bash
./gradlew detekt
```

## CI/CD Integration

The GitHub Actions workflow `.github/workflows/jetbrains-compliance.yml` runs compliance checks on every PR and push.

## Running Locally

### Quick Compliance Check
```bash
# Run JetBrains compliance check
./scripts/jetbrains-compliance-check.sh
```

### Full Code Quality Check
```bash
# Run detekt for code quality
./gradlew detekt

# View HTML report
open build/reports/detekt/detekt.html
```

## Understanding Results

### Compliance Check Results

- **✅ No critical violations**: Code complies with JetBrains requirements
- **❌ Critical violations**: Must be fixed before auto-approval
- **⚠️ Warnings**: Should be reviewed but may be acceptable

### Common Warnings

1. **Manual thread creation**: If you see warnings about thread creation:
- Prefer coroutines: `coroutineScope.launch { ... }`
- If using libraries with threads, ensure cleanup in `close()`

2. **Library imports**: If you see warnings about library imports:
- Verify the library isn't bundled in the final plugin
- Check that Toolbox doesn't already provide the library

3. **GlobalScope usage**: If you see warnings about `GlobalScope`:
- Use the coroutine scope provided by Toolbox instead

## Resources

- [JetBrains Toolbox Plugin Development](https://plugins.jetbrains.com/docs/toolbox/)
- [Detekt Documentation](https://detekt.dev/)
- [Kotlin Coroutines Guide](https://kotlinlang.org/docs/coroutines-guide.html)
18 changes: 18 additions & 0 deletionsbuild.gradle.kts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ plugins {
alias(libs.plugins.gradle.wrapper)
alias(libs.plugins.changelog)
alias(libs.plugins.gettext)
alias(libs.plugins.detekt)
}


Expand DownExpand Up@@ -110,6 +111,23 @@ tasks.test {
useJUnitPlatform()
}

// Detekt configuration for code quality
detekt {
buildUponDefaultConfig = true
allRules = false
}

// Configure detekt for code quality reporting
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor: we can do a static import here.

jvmTarget = "21"
reports {
html.required.set(true)
xml.required.set(true)
}
// Don't fail build on detekt issues - just report them
ignoreFailures = true
}


tasks.jar {
archiveBaseName.set(extension.id)
Expand Down
4 changes: 3 additions & 1 deletiongradle/libs.versions.toml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ changelog = "2.2.1"
gettext = "0.7.0"
plugin-structure = "3.308"
mockk = "1.14.4"
detekt = "1.23.7"

[libraries]
toolbox-core-api = { module = "com.jetbrains.toolbox:core-api", version.ref = "toolbox-plugin-api" }
Expand DownExpand Up@@ -45,4 +46,5 @@ dependency-license-report = { id = "com.github.jk1.dependency-license-report", v
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
gradle-wrapper = { id = "me.filippov.gradle.jvm.wrapper", version.ref = "gradle-wrapper" }
changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
gettext = { id = "name.kropp.kotlinx-gettext", version.ref = "gettext" }
gettext = { id = "name.kropp.kotlinx-gettext", version.ref = "gettext" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
102 changes: 102 additions & 0 deletionsscripts/jetbrains-compliance-check.sh
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
#!/bin/bash
Copy link
Collaborator

Choose a reason for hiding this comment

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

any reason for not configuring the rules in a detekt.yml?
https://detekt.dev/docs/rules/style/#forbiddenannotation


# JetBrains Auto-Approval Compliance Check Script
# This script checks for violations of JetBrains auto-approval requirements

set -e

echo "🔍 JetBrains Auto-Approval Compliance Check"
echo "==========================================="
echo

VIOLATIONS=0
SOURCE_DIR="src/main/kotlin"

# Function to report violations
report_violation() {
echo "❌ VIOLATION: $1"
echo " File: $2"
echo " Line: $3"
echo " Context: $4"
echo
VIOLATIONS=$((VIOLATIONS + 1))
}

# Function to report warnings
report_warning() {
echo "⚠️ WARNING: $1"
echo " File: $2"
echo " Line: $3"
echo " Context: $4"
echo
}

echo "1. Checking for experimental API usage..."
# Check for forbidden experimental annotations (excluding acceptable coroutines ones)
grep -rn "@ExperimentalApi\|@ExperimentalStdlibApi\|@ExperimentalUnsignedTypes\|@ExperimentalContracts\|@ExperimentalTypeInference\|@InternalCoroutinesApi\|@ExperimentalTime" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_violation "Forbidden experimental API usage" "$file" "$line" "$content"
done

# Check for @OptIn with forbidden experimental APIs
grep -rn "@OptIn.*ExperimentalApi\|@OptIn.*ExperimentalStdlibApi\|@OptIn.*InternalCoroutinesApi" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_violation "@OptIn with forbidden experimental API" "$file" "$line" "$content"
done

echo "2. Checking for manual thread creation..."
# Check for direct thread creation
grep -rn "Thread(\|ThreadPoolExecutor\|ScheduledThreadPoolExecutor\|ForkJoinPool\|Timer(\|TimerTask" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_warning "Manual thread creation detected - ensure proper cleanup in CoderRemoteProvider#close()" "$file" "$line" "$content"
done

# Check for Executors usage
grep -rn "Executors\.new\|CompletableFuture\.runAsync\|CompletableFuture\.supplyAsync" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_warning "Executor/CompletableFuture usage detected - ensure proper cleanup in CoderRemoteProvider#close()" "$file" "$line" "$content"
done

# Check for classes extending Thread or implementing Runnable
grep -rn "class.*extends Thread\|class.*implements Runnable\|: Thread\|: Runnable" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_warning "Class extending Thread or implementing Runnable - consider using coroutines" "$file" "$line" "$content"
done

echo "3. Checking for Java runtime hooks..."
# Check for runtime hooks
grep -rn "Runtime\..*addShutdownHook\|System\.setSecurityManager\|setUncaughtExceptionHandler\|setDefaultUncaughtExceptionHandler" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_violation "Java runtime hook usage forbidden" "$file" "$line" "$content"
done

# Check for suspicious system property modifications
grep -rn "System\.setProperty.*java\.security\|System\.setProperty.*java\.awt\.headless\|System\.setProperty.*file\.encoding" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_violation "Suspicious system property modification" "$file" "$line" "$content"
done

echo "4. Checking for bundled libraries..."
# Check for imports that might indicate bundled libraries
grep -rn "import org\.slf4j\|import org\.jetbrains\.annotations" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_warning "Import of potentially bundled library - ensure it's not bundled" "$file" "$line" "$content"
done

echo "5. Checking for coroutines best practices..."
# Check for GlobalScope usage (should use provided scope)
grep -rn "GlobalScope\.launch\|GlobalScope\.async" $SOURCE_DIR 2>/dev/null | while IFS=: read -r file line content; do
report_warning "GlobalScope usage detected - consider using provided coroutine scope" "$file" "$line" "$content"
done

echo "==========================================="
if [ $VIOLATIONS -eq 0 ]; then
echo "✅ No critical violations found!"
echo " Your code appears to comply with JetBrains auto-approval requirements."
echo
echo "📋 Summary of requirements:"
echo " ✓ No forbidden Kotlin experimental APIs"
echo " ✓ No Java runtime hooks"
echo " ✓ No suspicious system modifications"
echo " ⚠️ Manual thread creation warnings (if any) - ensure cleanup in close()"
echo " ⚠️ Library bundling warnings (if any) - verify not bundling Toolbox libs"
echo
exit 0
else
echo "❌ Found $VIOLATIONS critical violations!"
echo " Please fix these issues before submitting for auto-approval."
echo
exit 1
fi
Loading

[8]ページ先頭

©2009-2025 Movatter.jp