diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2457077 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +* text=auto + +gradlew text eol=lf +*.sh text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf + +*.jar binary +*.zip binary +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..c6018a7 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +* @ByteAurora + diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..7b3f214 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,47 @@ +name: Bug report +description: Report a reproducible CodeXP issue +title: "[Bug]: " +labels: ["bug"] +body: + - type: textarea + id: description + attributes: + label: Description + description: What happened? + validations: + required: true + - type: input + id: plugin-version + attributes: + label: CodeXP version + placeholder: "2.1.0" + validations: + required: true + - type: input + id: ide-version + attributes: + label: IDE and version + placeholder: "IntelliJ IDEA 2026.1" + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce + placeholder: | + 1. + 2. + 3. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + validations: + required: true + - type: textarea + id: logs + attributes: + label: Logs or screenshots + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0086358 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..80c9008 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,24 @@ +name: Feature request +description: Suggest a focused improvement for CodeXP +title: "[Feature]: " +labels: ["enhancement"] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What user problem would this solve? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposal + description: Describe the behavior you want. + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives + diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9be205f..2093cdf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,17 +1,15 @@ -# Dependabot configuration: -# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates - version: 2 updates: - # Maintain dependencies for Gradle dependencies - - package-ecosystem: "gradle" + - package-ecosystem: gradle directory: "/" - target-branch: "next" + target-branch: develop schedule: - interval: "daily" - # Maintain dependencies for GitHub Actions - - package-ecosystem: "github-actions" + interval: weekly + open-pull-requests-limit: 5 + + - package-ecosystem: github-actions directory: "/" - target-branch: "next" + target-branch: develop schedule: - interval: "daily" + interval: weekly + open-pull-requests-limit: 5 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..36153f5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +## Summary + +## Validation + +- [ ] `./gradlew check koverXmlReport buildPlugin` +- [ ] `./gradlew verifyPlugin` if compatibility, build, or release behavior changed + +## Notes diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml deleted file mode 100644 index 1ad8190..0000000 --- a/.github/workflows/build_develop.yml +++ /dev/null @@ -1,95 +0,0 @@ -# GitHub Actions Workflow is created for testing and preparing the plugin release in the following steps: -# - validate Gradle Wrapper, -# - run 'test' and 'verifyPlugin' tasks, -# - run Qodana inspections, -# - run 'buildPlugin' task and prepare artifact for the further tests, -# - run 'runPluginVerifier' task, -# - create a draft release. -# -# Workflow is triggered on push and pull_request events. -# -# GitHub Actions reference: https://help.github.com/en/actions -# -## JBIJPPTPL - -name: Build on develop -on: - # Trigger the workflow on pushes to only the 'develop' branch (this avoids duplicate checks being run e.g. for dependabot pull requests) - push: - branches: [develop] - # Trigger the workflow on any pull request - pull_request: - branches: [develop] - -jobs: - - # Run Gradle Wrapper Validation Action to verify the wrapper's checksum - # Run verifyPlugin, IntelliJ Plugin Verifier, and test Gradle tasks - # Build plugin and provide the artifact for the next workflow jobs - build: - name: Build - runs-on: ubuntu-latest - outputs: - version: ${{ steps.properties.outputs.version }} - changelog: ${{ steps.properties.outputs.changelog }} - steps: - - # Free GitHub Actions Environment Disk Space - - name: Maximize Build Space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - - # Check out current repository - - name: Fetch Sources - uses: actions/checkout@v3 - - # Validate wrapper - - name: Gradle Wrapper Validation - uses: gradle/wrapper-validation-action@v1.0.6 - - # Setup Java 11 environment for the next steps - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: zulu - java-version: 11 - - # Set environment variables - - name: Export Properties - id: properties - shell: bash - run: | - PROPERTIES="$(./gradlew properties --console=plain -q)" - VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')" - NAME="$(echo "$PROPERTIES" | grep "^pluginName:" | cut -f2- -d ' ')" - CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)" - - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "name=$NAME" >> $GITHUB_OUTPUT - echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT - - echo "changelog<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - ./gradlew listProductsReleases # prepare list of IDEs for Plugin Verifier - - # Run tests - - name: Run Tests - run: ./gradlew check - - # Collect Tests Result of failed tests - - name: Collect Tests Result - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: tests-result - path: ${{ github.workspace }}/build/reports/tests - - # Upload Kover report to CodeCov - - name: Upload Code Coverage Report - uses: codecov/codecov-action@v3 - with: - files: ${{ github.workspace }}/build/reports/kover/xml/report.xml diff --git a/.github/workflows/build_main.yml b/.github/workflows/build_main.yml deleted file mode 100644 index 2531abc..0000000 --- a/.github/workflows/build_main.yml +++ /dev/null @@ -1,173 +0,0 @@ -# GitHub Actions Workflow is created for testing and preparing the plugin release in the following steps: -# - validate Gradle Wrapper, -# - run 'test' and 'verifyPlugin' tasks, -# - run Qodana inspections, -# - run 'buildPlugin' task and prepare artifact for the further tests, -# - run 'runPluginVerifier' task, -# - create a draft release. -# -# Workflow is triggered on push and pull_request events. -# -# GitHub Actions reference: https://help.github.com/en/actions -# -## JBIJPPTPL - -name: Build on main -on: - # Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g. for dependabot pull requests) - push: - branches: [main] - # Trigger the workflow on pull request to the 'main' branch - pull_request: - branches: [main] - -jobs: - - # Run Gradle Wrapper Validation Action to verify the wrapper's checksum - # Run verifyPlugin, IntelliJ Plugin Verifier, and test Gradle tasks - # Build plugin and provide the artifact for the next workflow jobs - build: - name: Build - runs-on: ubuntu-latest - outputs: - version: ${{ steps.properties.outputs.version }} - changelog: ${{ steps.properties.outputs.changelog }} - steps: - - # Free GitHub Actions Environment Disk Space - - name: Maximize Build Space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - - # Check out current repository - - name: Fetch Sources - uses: actions/checkout@v3 - - # Validate wrapper - - name: Gradle Wrapper Validation - uses: gradle/wrapper-validation-action@v1.0.6 - - # Setup Java 11 environment for the next steps - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: zulu - java-version: 11 - - # Set environment variables - - name: Export Properties - id: properties - shell: bash - run: | - PROPERTIES="$(./gradlew properties --console=plain -q)" - VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')" - NAME="$(echo "$PROPERTIES" | grep "^pluginName:" | cut -f2- -d ' ')" - CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)" - - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "name=$NAME" >> $GITHUB_OUTPUT - echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT - - echo "changelog<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - ./gradlew listProductsReleases # prepare list of IDEs for Plugin Verifier - - # Run tests - - name: Run Tests - run: ./gradlew check - - # Collect Tests Result of failed tests - - name: Collect Tests Result - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: tests-result - path: ${{ github.workspace }}/build/reports/tests - - # Upload Kover report to CodeCov - - name: Upload Code Coverage Report - uses: codecov/codecov-action@v3 - with: - files: ${{ github.workspace }}/build/reports/kover/xml/report.xml - - # Cache Plugin Verifier IDEs - - name: Setup Plugin Verifier IDEs Cache - uses: actions/cache@v3 - with: - path: ${{ steps.properties.outputs.pluginVerifierHomeDir }}/ides - key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }} - - # Run Verify Plugin task and IntelliJ Plugin Verifier tool - - name: Run Plugin Verification tasks - run: ./gradlew runPluginVerifier -Dplugin.verifier.home.dir=${{ steps.properties.outputs.pluginVerifierHomeDir }} - - # Collect Plugin Verifier Result - - name: Collect Plugin Verifier Result - if: ${{ always() }} - uses: actions/upload-artifact@v4 - with: - name: pluginVerifier-result - path: ${{ github.workspace }}/build/reports/pluginVerifier - - # Run Qodana inspections - - name: Qodana - Code Inspection - uses: JetBrains/qodana-action@v2022.3.4 - - # Prepare plugin archive content for creating artifact - - name: Prepare Plugin Artifact - id: artifact - shell: bash - run: | - cd ${{ github.workspace }}/build/distributions - FILENAME=`ls *.zip` - unzip "$FILENAME" -d content - - echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT - - # Store already-built plugin as an artifact for downloading - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.artifact.outputs.filename }} - path: ./build/distributions/content/*/* - - # Prepare a draft release for GitHub Releases page for the manual verification - # If accepted and published, release workflow would be triggered - releaseDraft: - name: Release Draft - if: github.event_name != 'pull_request' - needs: build - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - # Check out current repository - - name: Fetch Sources - uses: actions/checkout@v3 - - # Remove old release drafts by using the curl request for the available releases with a draft flag - - name: Remove Old Release Drafts - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh api repos/{owner}/{repo}/releases \ - --jq '.[] | select(.draft == true) | .id' \ - | xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{} - - # Create a new release draft which is not publicly visible and requires manual acceptance - - name: Create Release Draft - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release create v${{ needs.build.outputs.version }} \ - --draft \ - --title "v${{ needs.build.outputs.version }}" \ - --notes "$(cat << 'EOM' - ${{ needs.build.outputs.changelog }} - EOM - )" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..68d8920 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,117 @@ +name: CI + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build, test, and verify + runs-on: ubuntu-latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + steps: + - name: Maximize build space + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + large-packages: false + + - name: Fetch sources + uses: actions/checkout@v6 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: zulu + java-version: 21 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + + - name: Check, package, and verify plugin + run: ./gradlew check koverXmlReport buildPlugin verifyPlugin + + - name: Upload plugin artifact + uses: actions/upload-artifact@v6 + with: + name: intellij-codexp-plugin + path: build/distributions/*.zip + if-no-files-found: error + + - name: Upload test report + if: ${{ failure() }} + uses: actions/upload-artifact@v6 + with: + name: test-report + path: build/reports/tests + if-no-files-found: ignore + + - name: Upload plugin verifier report + if: ${{ always() }} + uses: actions/upload-artifact@v6 + with: + name: plugin-verifier-report + path: build/reports/pluginVerifier + if-no-files-found: ignore + + - name: Upload coverage + if: ${{ env.CODECOV_TOKEN != '' }} + uses: codecov/codecov-action@v5 + with: + files: build/reports/kover/report.xml + token: ${{ env.CODECOV_TOKEN }} + + release-draft: + name: Release draft + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + needs: [build] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Fetch sources + uses: actions/checkout@v6 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: zulu + java-version: 21 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: true + + - name: Create release draft + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + VERSION="$(./gradlew properties --property version --quiet --console=plain | tail -n 1 | cut -f2- -d ' ')" + RELEASE_NOTE="./build/tmp/release_note.txt" + ./gradlew getChangelog --unreleased --no-header --quiet --console=plain --output-file="$RELEASE_NOTE" + + if gh release view "v${VERSION}" >/dev/null 2>&1; then + IS_DRAFT="$(gh release view "v${VERSION}" --json isDraft --jq '.isDraft')" + if [ "$IS_DRAFT" != "true" ]; then + echo "Release v${VERSION} already exists and is not a draft." + exit 1 + fi + gh release delete "v${VERSION}" --cleanup-tag --yes + fi + + gh release create "v${VERSION}" \ + --draft \ + --title "v${VERSION}" \ + --notes-file "$RELEASE_NOTE" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c4c9b1..b6eacad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,60 +1,57 @@ -# 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 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. - name: Release + on: release: - types: [prereleased, released] + types: [published] jobs: - - # Prepare and publish the plugin to the Marketplace repository release: - name: Publish Plugin + name: Publish plugin + if: ${{ github.repository == 'ByteAurora/intellij-codexp' && github.actor == 'ByteAurora' }} runs-on: ubuntu-latest + environment: + name: jetbrains-marketplace + url: https://plugins.jetbrains.com/plugin/21896-codexp permissions: contents: write - pull-requests: write steps: - - # Check out current repository - - name: Fetch Sources - uses: actions/checkout@v3 + - name: Fetch sources + uses: actions/checkout@v6 with: ref: ${{ github.event.release.tag_name }} - # Setup Java 11 environment for the next steps - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: distribution: zulu - java-version: 11 + java-version: 21 - # Set environment variables - - name: Export Properties - id: properties + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + + - name: Export release notes + id: release-notes shell: bash run: | CHANGELOG="$(cat << 'EOM' | sed -e 's/^[[:space:]]*$//g' -e '/./,$!d' ${{ github.event.release.body }} EOM )" - - echo "changelog<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - # Update Unreleased section with the current release note - - name: Patch Changelog - if: ${{ steps.properties.outputs.changelog != '' }} + echo "changelog<> "$GITHUB_OUTPUT" + echo "$CHANGELOG" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Patch changelog + if: ${{ steps.release-notes.outputs.changelog != '' }} env: - CHANGELOG: ${{ steps.properties.outputs.changelog }} - run: | - ./gradlew patchChangelog --release-note="$CHANGELOG" + CHANGELOG: ${{ steps.release-notes.outputs.changelog }} + run: ./gradlew patchChangelog --release-note="$CHANGELOG" + + - name: Verify release build + run: ./gradlew check buildPlugin verifyPlugin - # Publish the plugin to the Marketplace - - name: Publish Plugin + - name: Publish plugin env: PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }} @@ -62,8 +59,7 @@ jobs: PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }} run: ./gradlew publishPlugin - # Upload artifact as a release asset - - name: Upload Release Asset + - name: Upload release asset env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/* \ No newline at end of file + run: gh release upload "${{ github.event.release.tag_name }}" ./build/distributions/* diff --git a/.github/workflows/run-ui-tests.yml b/.github/workflows/run-ui-tests.yml deleted file mode 100644 index 363d9e8..0000000 --- a/.github/workflows/run-ui-tests.yml +++ /dev/null @@ -1,59 +0,0 @@ -# GitHub Actions Workflow for launching UI tests on Linux, Windows, and Mac in the following steps: -# - prepare and launch IDE with your plugin and robot-server plugin, which is needed to interact with UI -# - wait for IDE to start -# - run UI tests with separate Gradle task -# -# Please check https://github.com/JetBrains/intellij-ui-test-robot for information about UI tests with IntelliJ Platform -# -# Workflow is triggered manually. - -name: Run UI Tests -on: - workflow_dispatch - -jobs: - - testUI: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - runIde: | - export DISPLAY=:99.0 - Xvfb -ac :99 -screen 0 1920x1080x16 & - gradle runIdeForUiTests & - - os: windows-latest - runIde: start gradlew.bat runIdeForUiTests - - os: macos-latest - runIde: ./gradlew runIdeForUiTests & - - steps: - - # Check out current repository - - name: Fetch Sources - uses: actions/checkout@v3 - - # Setup Java 11 environment for the next steps - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: zulu - java-version: 11 - - # Run IDEA prepared for UI testing - - name: Run IDE - run: ${{ matrix.runIde }} - - # Wait for IDEA to be started - - name: Health Check - uses: jtalk/url-health-check-action@v3 - with: - url: http://127.0.0.1:8082 - max-attempts: 15 - retry-delay: 30s - - # Run tests - - name: Tests - run: ./gradlew test diff --git a/.gitignore b/.gitignore index f55805a..8dc361f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,28 @@ -.gradle -.idea -.qodana -build -secrets \ No newline at end of file +.gradle/ +.intellijPlatform/ +.idea/ +.qodana/ +.kotlin/ +build/ +out/ + +*.iml +*.iws +*.ipr +*.log +*.hprof +.DS_Store + +local.properties +.env +.env.* +!.env.example + +secrets/ +.codexp-signing/ +*.pem +*.key +*.p12 +*.jks +*.keystore +*.crt diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 1ace7cf..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.run/Run IDE for UI Tests.run.xml b/.run/Run IDE for UI Tests.run.xml deleted file mode 100644 index 57d58cd..0000000 --- a/.run/Run IDE for UI Tests.run.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - true - true - false - false - - - \ No newline at end of file diff --git a/.run/Run Qodana.run.xml b/.run/Run Qodana.run.xml deleted file mode 100644 index 747f467..0000000 --- a/.run/Run Qodana.run.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - true - true - false - false - - - \ No newline at end of file diff --git a/.run/Run Verifications.run.xml b/.run/Run Verifications.run.xml index 0d2e810..7554cba 100644 --- a/.run/Run Verifications.run.xml +++ b/.run/Run Verifications.run.xml @@ -11,7 +11,7 @@