diff --git a/.github/workflows/milestone.yml b/.github/workflows/milestone.yml new file mode 100644 index 00000000..b201c282 --- /dev/null +++ b/.github/workflows/milestone.yml @@ -0,0 +1,56 @@ +name: Close Milestone on Release +on: + release: + types: [published] + workflow_dispatch: + inputs: + milestone_tag: + description: 'Specify Release Tag (e.g., v1.2.3). Leave empty for LATEST.' + required: false + default: '' +jobs: + close_milestone: + runs-on: ubuntu-latest + permissions: + issues: write + contents: read + steps: + - name: Determine Target Release Tag + id: determine_tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [[ "${{ github.event_name }}" == "release" ]]; then + RELEASE_TAG="${{ github.event.release.tag_name }}" + elif [[ -n "${{ github.event.inputs.milestone_tag }}" ]]; then + RELEASE_TAG="${{ github.event.inputs.milestone_tag }}" + else + RELEASE_TAG=$(gh api repos/${{ github.repository }}/releases/latest --jq '.tag_name') + fi + # Strip 'v' prefix + MILESTONE_TITLE="${RELEASE_TAG#v}" + echo "MILESTONE_TITLE=$MILESTONE_TITLE" >> $GITHUB_OUTPUT + echo "Targeting Milestone: $MILESTONE_TITLE" + - name: Close Corresponding Milestone + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TITLE="${{ steps.determine_tag.outputs.MILESTONE_TITLE }}" + + # Find the milestone by title + MILESTONE_NUMBER=$(gh api repos/${{ github.repository }}/milestones \ + --jq ".[] | select(.title == \"$TITLE\") | .number") + + if [[ -z "$MILESTONE_NUMBER" ]]; then + echo "❌ Milestone '$TITLE' not found" + exit 1 + fi + + echo "Found milestone #$MILESTONE_NUMBER with title '$TITLE'" + + # Close the milestone + gh api repos/${{ github.repository }}/milestones/$MILESTONE_NUMBER \ + -X PATCH \ + -f state=closed + + echo "✅ Successfully closed milestone '$TITLE'" diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/ComponentMetaData.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/ComponentMetaData.java index 71708d31..3a69739e 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/ComponentMetaData.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/ComponentMetaData.java @@ -50,9 +50,10 @@ String fullName(boolean pkgPrivate) { everyType.addAll(factoryTypes); String topPackage = TopPackage.of(everyType); var defaultPackage = - !topPackage.contains(".") - && APContext.getProjectModuleElement().isUnnamed() - && APContext.elements().getPackageElement(topPackage) == null; + topPackage == null + || !topPackage.contains(".") + && APContext.getProjectModuleElement().isUnnamed() + && APContext.elements().getPackageElement(topPackage) == null; if (!defaultPackage && !pkgPrivate && !topPackage.endsWith(".jsonb")) { topPackage += ".jsonb"; } diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java index 90e9ba08..fd5e32b6 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java @@ -122,11 +122,11 @@ public boolean process(Set annotations, RoundEnvironment generateComponent = rounds++ > 0; APContext.setProjectModuleElement(annotations, round); readModule(); - getElements(round, ValuePrism.PRISM_TYPE).ifPresent(this::writeValueAdapters); - getElements(round, JSON).ifPresent(this::writeAdapters); - getElements(round, JSON_MIXIN).ifPresent(this::writeAdaptersForMixInTypes); - getElements(round, JSON_IMPORT_LIST).ifPresent(this::writeAdaptersForImportedList); - getElements(round, JSON_IMPORT).ifPresent(this::writeAdaptersForImported); + getJsonElements(round, ValuePrism.PRISM_TYPE).ifPresent(this::writeValueAdapters); + getJsonElements(round, JSON).ifPresent(this::writeAdapters); + getJsonElements(round, JSON_MIXIN).ifPresent(this::writeAdaptersForMixInTypes); + getJsonElements(round, JSON_IMPORT_LIST).ifPresent(this::writeAdaptersForImportedList); + getJsonElements(round, JSON_IMPORT).ifPresent(this::writeAdaptersForImported); getElements(round, "io.avaje.spi.ServiceProvider").ifPresent(this::registerSPI); getElements(round, CustomAdapterPrism.PRISM_TYPE).ifPresent(this::registerCustomAdapters); @@ -137,7 +137,15 @@ public boolean process(Set annotations, RoundEnvironment } // Optional because annotations are not guaranteed to exist - private Optional> getElements(RoundEnvironment round, String name) { + private Optional> getElements( + RoundEnvironment round, String name) { + return Optional.ofNullable(typeElement(name)) + .map(round::getElementsAnnotatedWith) + .filter(n -> !n.isEmpty()); + } + + // Optional because annotations are not guaranteed to exist + private Optional> getJsonElements(RoundEnvironment round, String name) { var op = Optional.ofNullable(typeElement(name)) .map(round::getElementsAnnotatedWith)