Skip to content

Commit 4816132

Browse files
whitewhite
authored andcommitted
Merge branch 'feat/shared-build-common'
2 parents 3b67f6b + 631b4ec commit 4816132

48 files changed

Lines changed: 3861 additions & 717 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Publish build-common
2+
3+
on:
4+
push:
5+
tags: ['build-common-v*']
6+
workflow_dispatch:
7+
8+
jobs:
9+
build-common-maven-central:
10+
name: Publish build-common to Maven Central
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up JDK 17
18+
uses: actions/setup-java@v4
19+
with:
20+
java-version: '17'
21+
distribution: 'temurin'
22+
23+
- name: Set up Gradle
24+
uses: gradle/actions/setup-gradle@v4
25+
26+
- name: Make gradlew executable
27+
run: chmod +x gradlew
28+
29+
- name: Extract version from tag
30+
id: version
31+
run: |
32+
if [[ "$GITHUB_REF" == refs/tags/build-common-v* ]]; then
33+
echo "VERSION=${GITHUB_REF_NAME#build-common-v}" >> $GITHUB_OUTPUT
34+
fi
35+
36+
- name: Build
37+
run: ./gradlew :python-embed-build-common:build${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
38+
39+
- name: Publish to Maven Central
40+
run: ./gradlew :python-embed-build-common:publishToMavenCentral --no-configuration-cache${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
41+
env:
42+
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
43+
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
44+
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }}
45+
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_IN_MEMORY_KEY_ID }}
46+
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_IN_MEMORY_KEY_PASSWORD }}
47+
48+
- name: Create GitHub Release
49+
if: steps.version.outputs.VERSION != ''
50+
uses: softprops/action-gh-release@v2
51+
with:
52+
name: "python-embed-build-common v${{ steps.version.outputs.VERSION }}"
53+
generate_release_notes: true

.github/workflows/publish-gradle-plugin.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ jobs:
1111
runs-on: ubuntu-latest
1212
permissions:
1313
contents: write
14-
defaults:
15-
run:
16-
working-directory: python-embed-gradle-plugin
1714
steps:
1815
- uses: actions/checkout@v4
1916

@@ -34,21 +31,19 @@ jobs:
3431
run: |
3532
if [[ "$GITHUB_REF" == refs/tags/plugin-v* ]]; then
3633
echo "VERSION=${GITHUB_REF_NAME#plugin-v}" >> $GITHUB_OUTPUT
37-
else
38-
echo "VERSION=1.0.2" >> $GITHUB_OUTPUT
3934
fi
4035
4136
- name: Build
42-
run: ./gradlew build -PreleaseVersion=${{ steps.version.outputs.VERSION }}
37+
run: ./gradlew :python-embed-gradle-plugin:build${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
4338

4439
- name: Publish to Gradle Plugin Portal
45-
run: ./gradlew publishPlugins -PreleaseVersion=${{ steps.version.outputs.VERSION }}
40+
run: ./gradlew :python-embed-gradle-plugin:publishPlugins --no-configuration-cache${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
4641
env:
4742
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
4843
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
4944

5045
- name: Create GitHub Release
51-
if: startsWith(github.ref, 'refs/tags/')
46+
if: steps.version.outputs.VERSION != ''
5247
uses: softprops/action-gh-release@v2
5348
with:
5449
name: "python-embed-gradle-plugin v${{ steps.version.outputs.VERSION }}"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Publish Maven Plugin
2+
3+
on:
4+
push:
5+
tags: ['maven-plugin-v*']
6+
workflow_dispatch:
7+
8+
jobs:
9+
maven-plugin-maven-central:
10+
name: Publish Maven Plugin to Maven Central
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up JDK 17
18+
uses: actions/setup-java@v4
19+
with:
20+
java-version: '17'
21+
distribution: 'temurin'
22+
23+
- name: Set up Gradle
24+
uses: gradle/actions/setup-gradle@v4
25+
26+
- name: Make gradlew executable
27+
run: chmod +x gradlew
28+
29+
- name: Extract version from tag
30+
id: version
31+
run: |
32+
if [[ "$GITHUB_REF" == refs/tags/maven-plugin-v* ]]; then
33+
echo "VERSION=${GITHUB_REF_NAME#maven-plugin-v}" >> $GITHUB_OUTPUT
34+
fi
35+
36+
- name: Build
37+
run: ./gradlew :python-embed-maven-plugin:build${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
38+
39+
- name: Publish to Maven Central
40+
run: ./gradlew :python-embed-maven-plugin:publishToMavenCentral --no-configuration-cache${{ steps.version.outputs.VERSION && format(' -PreleaseVersion={0}', steps.version.outputs.VERSION) || '' }}
41+
env:
42+
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
43+
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
44+
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }}
45+
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_IN_MEMORY_KEY_ID }}
46+
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_IN_MEMORY_KEY_PASSWORD }}
47+
48+
- name: Create GitHub Release
49+
if: steps.version.outputs.VERSION != ''
50+
uses: softprops/action-gh-release@v2
51+
with:
52+
name: "python-embed-maven-plugin v${{ steps.version.outputs.VERSION }}"
53+
generate_release_notes: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.gradle/
22
build/
3+
!**/src/**/build/
34
!gradle/wrapper/gradle-wrapper.jar
45
.gradlelet/
56
*.iml

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [1.0.4] - 2026-06-26
4+
5+
- [python-embed-build-common](python-embed-build-common/CHANGELOG.md) (1.0.2) — shared build logic for Gradle/Maven plugins
6+
- [python-embed-maven-plugin](python-embed-maven-plugin/CHANGELOG.md) (1.0.2) — `python-embed:setup`, `python-embed:properties`, `python-embed:help` goals
7+
- [python-embed-gradle-plugin](python-embed-gradle-plugin/CHANGELOG.md) (1.0.3) — refactored to use build-common (~738→~188 lines in VenvTask)
8+
- Split publish workflows into per-module files (`publish-build-common.yml`, `publish-maven-plugin.yml`, `publish-gradle-plugin.yml`, etc.)
9+
310
## [1.0.3] - 2026-06-25
411

512
- [python-embed-spring-boot-starter](python-embed-spring-boot-starter/CHANGELOG.md) (1.0.3) — Fixed `NoClassDefFoundError` without Actuator, HealthIndicator bean isolation
@@ -39,6 +46,7 @@ Modules are now independently versioned with per-module changelogs:
3946
- Close hook support for resource cleanup
4047
- 13 example applications in `python-embed-examples`
4148

49+
[1.0.4]: See per-module changelogs above
4250
[1.0.3]: See per-module changelogs above
4351
[1.0.2]: See per-module changelogs above
4452
[1.0.1]: https://github.com/howtis/python-embed/releases/tag/v1.0.1

docs/installation.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Gradle Plugin
44

5+
[:fontawesome-brands-github: View source](https://github.com/howtis/python-embed/tree/main/python-embed-gradle-plugin)
6+
57
Add the plugin to `build.gradle`:
68

79
```groovy
@@ -53,6 +55,8 @@ The venv is rebuilt incrementally — only when dependencies change.
5355

5456
## Spring Boot Starter
5557

58+
[:fontawesome-brands-github: View source](https://github.com/howtis/python-embed/tree/main/python-embed-spring-boot-starter)
59+
5660
For Spring Boot 3.x applications, add the starter:
5761

5862
```groovy
@@ -63,8 +67,79 @@ dependencies {
6367

6468
This provides zero-code auto-configuration. See the [Spring Boot guide](spring-boot.md).
6569

70+
## Maven Plugin
71+
72+
[:fontawesome-brands-github: View source](https://github.com/howtis/python-embed/tree/main/python-embed-maven-plugin)
73+
74+
Add the plugin to `pom.xml`:
75+
76+
```xml
77+
<build>
78+
<plugins>
79+
<plugin>
80+
<groupId>io.github.howtis</groupId>
81+
<artifactId>python-embed-maven-plugin</artifactId>
82+
<version>1.0.2</version>
83+
<executions>
84+
<execution>
85+
<goals>
86+
<goal>setup</goal>
87+
</goals>
88+
</execution>
89+
</executions>
90+
<configuration>
91+
<packages>
92+
<package>numpy</package>
93+
<package>torch</package>
94+
</packages>
95+
</configuration>
96+
</plugin>
97+
</plugins>
98+
</build>
99+
```
100+
101+
### Goals
102+
103+
| Goal | Phase | Description |
104+
|------|-------|-------------|
105+
| `setup` | `generate-resources` | Creates a Python venv and installs packages |
106+
| `properties` | `generate-resources` | Generates `META-INF/python-embed.properties` for runtime discovery |
107+
| `help` || Displays usage information |
108+
109+
The `properties` goal automatically runs after `setup` via `@Execute`.
110+
111+
### Configuration
112+
113+
| Parameter | Type | Default | Description |
114+
|-----------|------|---------|-------------|
115+
| `packages` | `List<String>` | `[]` | Pip packages to install |
116+
| `pythonVersion` | `String` | `3.12` | Python version for auto-download |
117+
| `venvOutputDir` | `File` | `${project.build.directory}/python-venv` | Venv output directory |
118+
| `requirementsFile` | `File` || Path to `requirements.txt` |
119+
| `pyprojectTomlFile` | `File` || Path to `pyproject.toml` |
120+
| `pipIndexUrl` | `String` || Custom pip index URL |
121+
| `pipExtraArgs` | `List<String>` | `[]` | Extra pip install arguments |
122+
| `skip` | `boolean` | `false` | Skip plugin execution |
123+
| `targetOs` | `String` | auto-detected | Target OS: `windows`, `linux`, or `macos` |
124+
125+
### Usage
126+
127+
```bash
128+
# Run setup directly
129+
mvn python-embed:setup
130+
131+
# Generate properties
132+
mvn python-embed:properties
133+
134+
# Show help
135+
mvn python-embed:help
136+
137+
# Skip plugin execution
138+
mvn compile -Dpython-embed.skip=true
139+
```
140+
66141
## Requirements
67142

68143
- JDK 17+
69144
- Python 3.8+ (auto-downloaded if absent via python-build-standalone)
70-
- Gradle 8.x
145+
- Gradle 8.x (Gradle plugin) or Maven 3.9+ (Maven plugin)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Changelog
2+
3+
## [1.0.2] - 2026-06-26
4+
5+
### Added
6+
- `VenvManager` — shared venv setup logic extracted from Gradle plugin
7+
- `VenvConfig` — configuration record for venv setup
8+
- `PythonDownloader` — downloads python-build-standalone releases from GitHub
9+
- `PythonResolver` — detects system Python and resolves python executable paths
10+
- `FingerprintManager` — incremental rebuild via package hash fingerprinting
11+
- `TarGzExtractor` — custom tar.gz extractor with path traversal protection
12+
- `RequirementsParser` — parses pip requirements.txt files
13+
14+
[build-common-v1.0.2]: https://github.com/howtis/python-embed/releases/tag/build-common-v1.0.2
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
plugins {
2+
id 'java-library'
3+
id 'com.vanniktech.maven.publish' version '0.34.0'
4+
}
5+
6+
group = 'io.github.howtis'
7+
version = project.findProperty('releaseVersion') ?: '1.0.2'
8+
9+
java {
10+
withSourcesJar()
11+
toolchain {
12+
languageVersion = JavaLanguageVersion.of(17)
13+
}
14+
}
15+
16+
mavenPublishing {
17+
publishToMavenCentral(true)
18+
signAllPublications()
19+
pom {
20+
name = 'python-embed-build-common'
21+
description = 'Shared build utilities for python-embed Gradle and Maven plugins'
22+
url = 'https://github.com/howtis/python-embed'
23+
licenses {
24+
license {
25+
name = 'MIT License'
26+
url = 'https://opensource.org/licenses/MIT'
27+
}
28+
}
29+
developers {
30+
developer {
31+
id = 'howtis'
32+
name = 'howtis'
33+
url = 'https://github.com/howtis'
34+
}
35+
}
36+
scm {
37+
url = 'https://github.com/howtis/python-embed'
38+
connection = 'scm:git:git://github.com/howtis/python-embed.git'
39+
developerConnection = 'scm:git:ssh://github.com/howtis/python-embed.git'
40+
}
41+
}
42+
}
43+
44+
repositories {
45+
mavenCentral()
46+
}
47+
48+
dependencies {
49+
testImplementation platform('org.junit:junit-bom:5.11.4')
50+
testImplementation 'org.junit.jupiter:junit-jupiter'
51+
}
52+
53+
tasks.named('jar') {
54+
metaInf {
55+
from rootProject.file('../LICENSE')
56+
}
57+
}
58+
59+
test {
60+
useJUnitPlatform()
61+
}
45.1 KB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)