ื ื™ืฆืŸ Gradle ืื•ืŸ Github ืึทืงืฉืึทื ื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ Java Project ืฆื• Sonatype Maven Central Repository

ืื™ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ, ืื™ืš ื•ื•ื™ืœืŸ ืฆื• ื ืขืžืขืŸ ืึท ื ืขืขื ื˜ืขืจ ืงื•ืง ืื™ืŸ ื“ืขื ืคึผืจืึธืฆืขืก ืคื•ืŸ ืืจื•ื™ืกื’ืขื‘ืŸ ืึท ื“ื–ืฉืึทื•ื•ืึท ืึทืจื˜ืึทืคืึทืงื˜ ืคึฟื•ืŸ ืงืจืึทืฆืŸ ื“ื•ืจืš Github ืึทืงืฉืึทื ื– ืื™ืŸ ื“ื™ Sonatype Maven ืกืขื ื˜ืจืึทืœ ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ื ื™ืฆืŸ ื“ื™ Gradle ืงืึทืœืขืงื˜ืขืจ.

ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ ืจืขื›ื˜ ืฆื• ื“ืขืจ ืคืขืœืŸ ืคื•ืŸ ืึท ื ืึธืจืžืึทืœ ื˜ื•ื˜ืึธืจื™ืึทืœ ืื™ืŸ ืื™ื™ืŸ ืึธืจื˜. ื“ ื™ ืืœ ืข ืื™ื ืคืืจืžืืฆื™ืข ื ื”ืื‘ ืŸ ื’ืขืžื•ื– ื˜ ื–ืืžืœืข ืŸ ืฉื˜ื™ืง ืœ ืฉื˜ื™ืง ืœ ืคื• ืŸ ืคืืจืฉืฒื“ืขื  ืข ืงืฐืืœืŸ , ืื• ืŸ ื ื™ืฉ ื˜ ืื™ื ื’ืื ืฆ ืŸ ืคืจื™ืฉืข . ื•ื•ืขืจ ืขืก ื™ื– ืื™ื ื˜ืขืจืขืกื™ืจื˜, ื‘ืึทื’ืจื™ืกื•ื ื’ ืฆื• ืงืึทืฅ.

ืฉืึทืคึฟืŸ ืึท ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ืื™ืŸ Sonatype

ื“ืขืจ ืขืจืฉื˜ืขืจ ืฉืจื™ื˜ ืื™ื– ืฆื• ืฉืึทืคึฟืŸ ืึท ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ืื™ืŸ Sonatype Maven Central. ืคึฟืึทืจ ื“ืขื ืžื™ืจ ื’ื™ื™ืŸ ื“ืึธ, ืคืึทืจืฉืจื™ื™ึทื‘ืŸ ืื•ืŸ ืฉืึทืคึฟืŸ ืึท ื ื™ื™ึทืข ืึทืจื‘ืขื˜ ืžื™ื˜ ืึท ื‘ืงืฉื” ืฆื• ืฉืึทืคึฟืŸ ืึท ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ืคึฟืึทืจ ืื•ื ื“ื–. ืžื™ืจ ืคืึธืจ ืื™ืŸ ืื•ื ื“ื–ืขืจ GroupId ืคืจืื™ืขืงื˜, ืคึผืจืึธื™ืขืงื˜ URL ืœื™ื ืง ืฆื• ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื•ืŸ SCM URL ืึท ืœื™ื ืง ืฆื• ื“ื™ ื•ื•ืขืจืกื™ืข ืงืึธื ื˜ืจืึธืœ ืกื™ืกื˜ืขื ืื™ืŸ ื•ื•ืึธืก ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื™ื– ืœื™ื’ืŸ. GroupId ื“ืึธ ื–ืึธืœ ื–ื™ื™ืŸ ื•ื•ื™ com.example, com.example.domain, com.example.testsupport, ืื•ืŸ ืงืขื ืขืŸ ืื•ื™ืš ื–ื™ื™ืŸ ืื™ืŸ ื“ื™ ืคืึธืจืขื ืคื•ืŸ ืึท ืœื™ื ืง ืฆื• ื“ื™ื™ืŸ ื’ื™ื˜ื”ื•ื‘: github.com/yourusername -> io.github.yourusername. ืื™ืŸ ืงื™ื™ืŸ ืคืึทืœ, ืื™ืจ ื•ื•ืขื˜ ื“ืึทืจืคึฟืŸ ืฆื• ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ื“ื™ ืึธื•ื ืขืจืฉื™ืคึผ ืคื•ืŸ ื“ื™ ืคืขืœื“ ืึธื“ืขืจ ืคึผืจืึธืคื™ืœ. ืื•ื™ื‘ ืื™ืจ ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ืึท Github ืคึผืจืึธืคื™ืœ, ืื™ืจ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขื‘ืขื˜ืŸ ืฆื• ืฉืึทืคึฟืŸ ืึท ืขืคื ื˜ืœืขืš ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ืžื™ื˜ ื“ื™ ื’ืขื‘ืขื˜ืŸ ื ืึธืžืขืŸ.

ืขื˜ืœืขื›ืข ืžืึธืœ ื ืึธืš ื‘ืึทืฉื˜ืขื˜ื™ืงื•ื ื’, ื“ื™ื™ืŸ GroupId ื•ื•ืขื˜ ื–ื™ื™ืŸ ื‘ืืฉืืคืŸ ืื•ืŸ ืžื™ืจ ืงืขื ืขืŸ ืžืึทืš ืื•ื™ืฃ ืฆื• ื“ืขืจ ื•ื•ื™ื™ึทื˜ืขืจ ืฉืจื™ื˜, Gradle ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ.

ืงืึทื ืคื™ื’ื™ืขืจื™ื ื’ Gradle

ืื™ืŸ ื“ืขืจ ืฆื™ื™ื˜ ืคื•ืŸ ืฉืจื™ื™ื‘ืŸ, ืื™ืš ื”ืื‘ ื ื™ืฉื˜ ื’ืขืคื•ื ืขืŸ ืงื™ื™ืŸ ืคึผืœื•ื’ื™ื ืก ืคึฟืึทืจ Gradle ื•ื•ืึธืก ืงืขืŸ ื”ืขืœืคืŸ ืžื™ื˜ ืืจื•ื™ืกื’ืขื‘ืŸ ืึทืŸ ืึทืจื˜ืึทืคืึทืงื˜. ืขืก ื“ืขืจ ื‘ืœื•ื™ื– ืคึผืœื•ื’ื™ืŸ ื•ื•ืึธืก ืื™ืš ื’ืขืคึฟื•ื ืขืŸ, ืึธื‘ืขืจ ื“ืขืจ ืžื—ื‘ืจ ืืคื’ืขื–ืื’ื˜ ืฆื• ืฉื˜ื™ืฆืŸ ืขืก. ื“ืขืจื™ื‘ืขืจ, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื˜ืึธืŸ ืึทืœืฅ ื–ื™ืš, ืฆื•ืž ื’ืœื™ืง ืขืก ืื™ื– ื ื™ืฉื˜ ืฆื• ืฉื•ื•ืขืจ.

ื“ืขืจ ืขืจืฉื˜ืขืจ ื–ืึทืš ืฆื• ื’ืขืคึฟื™ื ืขืŸ ืื™ื– ื“ื™ ืืจื•ื™ืกื’ืขื‘ืŸ ืจืขืงื•ื•ื™ืจืขืžืขื ืฅ ืคื•ืŸ Sonatype. ื–ื™ื™ ื–ืขื ืขืŸ ื•ื•ื™ ื’ื™ื™ื˜:

  • ืึทื•ื•ืึทื™ืœืึทื‘ื™ืœื™ื˜ื™ ืคื•ืŸ ืžืงื•ืจ ืงืึธื•ื“ื– ืื•ืŸ JavaDoc, ื™.ืข. ืžื•ื–ืŸ ื–ื™ื™ืŸ ืคืึธืจืฉื˜ืขืœืŸ -sources.jar ะธ-javadoc.jar ื˜ืขืงืขืก. ื•ื•ื™ ืกื˜ื™ื™ื˜ื™ื“ ืื™ืŸ ื“ื™ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ, ืื•ื™ื‘ ืขืก ืื™ื– ื ื™ื˜ ืžืขื’ืœืขืš ืฆื• ืฆื•ืฉื˜ืขืœืŸ ืžืงื•ืจ ืงืึธื•ื“ื– ืึธื“ืขืจ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ, ืื™ืจ ืงืขื ืขืŸ ืžืึทื›ืŸ ืึท ื‘ืึธืง -sources.jar ืึธื“ืขืจ -javadoc.jar ืžื™ื˜ ืึท ืคึผืฉื•ื˜ README ื™ืŸ ืฆื• ืคืึธืจืŸ ื•ื•ืขืจืึทืคืึทืงื™ื™ืฉืึทืŸ.
  • ื›ืœ ื˜ืขืงืขืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ื’ืขื—ืชืžืขื˜ ืžื™ื˜ GPG/PGPืื•ืŸ .asc ื“ืขืจ ื˜ืขืงืข ืžื™ื˜ ื“ื™ ื›ืกื™ืžืข ืžื•ื–ืŸ ื–ื™ื™ืŸ ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ืคึฟืึทืจ ื™ืขื“ืขืจ ื˜ืขืงืข.
  • Availability pom ื˜ืขืงืข
  • ืจื™ื›ื˜ื™ืง ื•ื•ืึทืœื•ืขืก groupId, artifactId ะธ version. ื•ื•ืขืจืกื™ืข ืงืขื ืขืŸ ื–ื™ื™ืŸ ืึท ืึทืจื‘ื™ื˜ืจืึทืจื™ืฉ ืฉื˜ืจื™ืงืœ ืื•ืŸ ืงืขื ืขืŸ ื ื™ืฉื˜ ืกื•ืฃ ืžื™ื˜ -SNAPSHOT
  • ื‘ื™ื™ึทื–ื™ื™ึทืŸ ืคืืจืœืื ื’ื˜ name, description ะธ url
  • ื“ื™ ื‘ื™ื™ึทื–ื™ื™ึทืŸ ืคื•ืŸ ืื™ื ืคึฟืึธืจืžืึทืฆื™ืข ื•ื•ืขื’ืŸ ื“ื™ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ, ื“ืขื•ื•ืขืœืึธืคึผืขืจืก ืื•ืŸ ื•ื•ืขืจืกื™ืข ืงืึธื ื˜ืจืึธืœ ืกื™ืกื˜ืขื

ื“ืืก ื–ืขื ืขืŸ ื“ื™ ื’ืจื•ื ื˜ ื›ึผืœืœื™ื ื•ื•ืึธืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ื ืื›ื’ืขื’ืื ื’ืขืŸ ื•ื•ืขืŸ ืืจื•ื™ืกื’ืขื‘ืŸ. ืคื•ืœ ืื™ื ืคึฟืึธืจืžืึทืฆื™ืข ื‘ื ื™ืžืฆื ื“ืึธ.

ืžื™ืจ ื•ื•ืขืœืŸ ื™ื ืกื˜ืจื•ืžืขื ื˜ ื“ื™ ืจืขืงื•ื•ื™ืจืขืžืขื ืฅ ืื™ืŸ build.gradle ื˜ืขืงืข. ืขืจืฉื˜ืขืจ, ืœืึธื–ืŸ ืื•ื ื“ื– ืœื™ื™ื’ืŸ ืึทืœืข ื“ื™ ื ื™ื™ื˜ื™ืง ืื™ื ืคึฟืึธืจืžืึทืฆื™ืข ื•ื•ืขื’ืŸ ื“ื™ ื“ืขื•ื•ืขืœืึธืคึผืขืจืก, ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ, ื•ื•ืขืจืกื™ืข ืงืึธื ื˜ืจืึธืœ ืกื™ืกื˜ืขื, ืื•ืŸ ืื•ื™ืš ืฉื˜ืขืœืŸ ื“ื™ URL, ื ืึธืžืขืŸ ืื•ืŸ ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’ ืคื•ืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜. ืฆื• ื˜ืึธืŸ ื“ืึธืก, ืœืึธื–ืŸ ืื•ื ื“ื– ืฉืจื™ื™ึทื‘ืŸ ืึท ืคึผืฉื•ื˜ ืื•ืคึฟืŸ:

def customizePom(pom) {
    pom.withXml {
        def root = asNode()

        root.dependencies.removeAll { dep ->
            dep.scope == "test"
        }

        root.children().last() + {
            resolveStrategy = DELEGATE_FIRST

            description 'Some description of artifact'
            name 'Artifct name'
            url 'https://github.com/login/projectname'
            organization {
                name 'com.github.login'
                url 'https://github.com/login'
            }
            issueManagement {
                system 'GitHub'
                url 'https://github.com/login/projectname/issues'
            }
            licenses {
                license {
                    name 'The Apache License, Version 2.0'
                    url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                }
            }
            scm {
                url 'https://github.com/login/projectname'
                connection 'scm:https://github.com/login/projectname.git'
                developerConnection 'scm:git://github.com/login/projectname.git'
            }
            developers {
                developer {
                    id 'dev'
                    name 'DevName'
                    email '[email protected]'
                }
            }
        }
    }
}

ื•ื•ื™ื™ึทื˜ืขืจ ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ ืึทื– ื‘ืขืฉืึทืก ืคึฟืึทืจื–ืึทืžืœื•ื ื’ ื–ื™ื™ ื•ื•ืขืœืŸ ื“ื–ืฉืขื ืขืจื™ื™ื˜ -sources.jar ะธ-javadoc.jar ื˜ืขืงืขืก. ืฆื• ื˜ืึธืŸ ื“ืึธืก, ื’ื™ื™ืŸ ืฆื• ื“ื™ ืึธืคึผื˜ื™ื™ืœื•ื ื’ java ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืœื™ื™ื’ืŸ ื“ื™ ืคืืœื’ืขื ื“ืข:

java {
    withJavadocJar()
    withSourcesJar()
}

ืœืึธืžื™ืจ ื’ื™ื™ืŸ ืฆื• ื“ื™ ืœืขืฆื˜ืข ืคืึธื“ืขืจื•ื ื’, ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืึท ื’ืคึผื’ / ืคึผื’ืคึผ ื›ืกื™ืžืข. ืฆื• ื˜ืึธืŸ ื“ืึธืก, ืœืึธื–ืŸ ืื•ื ื“ื– ืคืึทืจื‘ื™ื ื“ืŸ ื“ื™ ืคึผืœื•ื’ื™ืŸ signing:

plugins {
    id 'signing'
}

ืื•ืŸ ืœื™ื™ื’ ื ื—ืœืง:

signing {
    sign publishing.publications
}

ืฆื•ื ืกื•ืฃ, ืœืึธืžื™ืจ ืฆื•ื’ืขื‘ืŸ ืึท ืึธืคึผื˜ื™ื™ืœื•ื ื’ publishing:

publishing {
    publications {
        mavenJava(MavenPublication) {
            customizePom(pom)
            groupId group
            artifactId archivesBaseName
            version version

            from components.java
        }
    }
    repositories {
        maven {
            url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            credentials {
                username sonatypeUsername
                password sonatypePassword
            }
        }
    }
}

ื“ืึธ sonatypeUsername ะธ sonatypePassword ื•ื•ืขืจื™ืึทื‘ืึทืœื– ืžื™ื˜ ื“ื™ ืœืึธื’ื™ืŸ ืื•ืŸ ืคึผืึทืจืึธืœ ื‘ืืฉืืคืŸ ื‘ืขืฉืึทืก ืจืขื’ื™ืกื˜ืจืึทืฆื™ืข ืื•ื™ืฃ sonatype.org.

ืึทื–ื•ื™ ื“ื™ ืœืขืฆื˜ build.gradle ื•ื•ืขื˜ ืงื•ืงืŸ ื•ื•ื™ ื“ืึธืก:

ื’ืึทื ืฅ build.gradle ืงืึธื“

plugins {
    id 'java'
    id 'maven-publish'
    id 'signing'
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
    withJavadocJar()
    withSourcesJar()
}

group 'io.github.githublogin'
archivesBaseName = 'projectname'
version = System.getenv('RELEASE_VERSION') ?: "0.0.1"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}

test {
    useJUnitPlatform()
}

jar {
    from sourceSets.main.output
    from sourceSets.main.allJava
}

signing {
    sign publishing.publications
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            customizePom(pom)
            groupId group
            artifactId archivesBaseName
            version version

            from components.java
        }
    }
    repositories {
        maven {
            url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            credentials {
                username sonatypeUsername
                password sonatypePassword
            }
        }
    }
}

def customizePom(pom) {
    pom.withXml {
        def root = asNode()

        root.dependencies.removeAll { dep ->
            dep.scope == "test"
        }

        root.children().last() + {
            resolveStrategy = DELEGATE_FIRST

            description 'Some description of artifact'
            name 'Artifct name'
            url 'https://github.com/login/projectname'
            organization {
                name 'com.github.login'
                url 'https://github.com/githublogin'
            }
            issueManagement {
                system 'GitHub'
                url 'https://github.com/githublogin/projectname/issues'
            }
            licenses {
                license {
                    name 'The Apache License, Version 2.0'
                    url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                }
            }
            scm {
                url 'https://github.com/githublogin/projectname'
                connection 'scm:https://github.com/githublogin/projectname.git'
                developerConnection 'scm:git://github.com/githublogin/projectname.git'
            }
            developers {
                developer {
                    id 'dev'
                    name 'DevName'
                    email '[email protected]'
                }
            }
        }
    }
}

ืื™ืš ื•ื•ืึธืœื˜ ื•ื•ื™ ืฆื• ื˜ืึธืŸ ืึทื– ืžื™ืจ ื‘ืึทืงื•ืžืขืŸ ื“ื™ ื•ื•ืขืจืกื™ืข ืคึฟื•ืŸ ื“ื™ ืกื•ื•ื™ื•ื•ืข ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง: System.getenv('RELEASE_VERSION'). ืžื™ืจ ื•ื•ืขืœืŸ ืฉื˜ืขืœืŸ ืขืก ื‘ืขืฉืึทืก ืคึฟืึทืจื–ืึทืžืœื•ื ื’ ืื•ืŸ ื ืขืžืขืŸ ืขืก ืคื•ืŸ ื“ื™ ืงื•ื•ื™ื˜ืœ ื ืึธืžืขืŸ.

PGP ืฉืœื™ืกืœ ื“ื•ืจ

ืื™ื™ื ืขืจ ืคื•ืŸ ื“ื™ ื‘ืื“ืขืจืคืขื ื™ืฉืŸ ืคื•ืŸ Sonatype ืื™ื– ืฆื• ืฆื™ื™ื›ืŸ ืึทืœืข ื˜ืขืงืขืก ืžื™ื˜ ืึท GPG / PGP ืฉืœื™ืกืœ. ืคึฟืึทืจ ื“ืขื ืžื™ืจ ื’ื™ื™ืŸ ื“ืึธ ืื•ืŸ ืืจืืคืงืืคื™ืข ื“ื™ GnuPG ื ื•ืฆืŸ ืคึฟืึทืจ ื“ื™ื™ืŸ ืึธืคึผืขืจื™ื™ื˜ื™ื ื’ ืกื™ืกื˜ืขื.

  • ืฉืึทืคึฟืŸ ืึท ืฉืœื™ืกืœ ืคึผืึธืจ: gpg --gen-key, ืึทืจื™ื™ึทืŸ ื“ื™ื™ืŸ ื ืืžืขืŸ, E- ืคึผืึธืกื˜, ืื•ืŸ ืื•ื™ืš ืฉื˜ืขืœืŸ ืึท ืคึผืึทืจืึธืœ.
  • ื–ืืœ ืก ื’ืขืคื™ื ืขืŸ ืื•ื™ืก id ืื•ื ื“ื–ืขืจ ืฉืœื™ืกืœ ืžื™ื˜ ื“ื™ ื‘ืึทืคึฟืขืœ: gpg --list-secret-keys --keyid-format short. ื ID ื•ื•ืขื˜ ื–ื™ื™ืŸ ืื ื’ืขื•ื•ื™ื–ืŸ ื ืึธืš ื“ื™ ืฆืขื”ืึทืงืŸ, ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ: rsa2048/9B695056
  • ืึทืจื•ื™ืกื’ืขื‘ืŸ ื“ืขื ืฆื™ื‘ื•ืจ ืฉืœื™ืกืœ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ https://keys.openpgp.org ื‘ืึทืคึฟืขืœ: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
  • ืžื™ืจ ืึทืจื•ื™ืกืคื™ืจืŸ ื“ืขื ืกื•ื“ ืฉืœื™ืกืœ ืฆื• ืึท ืึทืจื‘ื™ื˜ืจืึทืจื™ืฉ ืึธืจื˜; ืžื™ืจ ื•ื•ืขืœืŸ ื“ืึทืจืคึฟืŸ ืขืก ืฉืคึผืขื˜ืขืจ: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg

ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ Github ืึทืงืฉืึทื ื–

ืœืึธืžื™ืจ ื’ื™ื™ืŸ ืฆื• ื“ื™ ืœืขืฆื˜ ื‘ื™ื ืข, ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ื“ื™ ื‘ื•ื™ืขืŸ ืื•ืŸ ืึทื•ื˜ืึธ ืืจื•ื™ืกื’ืขื‘ืŸ ืžื™ื˜ Github Actions.
Github Actions ืื™ื– ืึท ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ื•ื•ืึธืก ืึทืœืึทื•ื– ืื™ืจ ืฆื• ืึธื˜ืึทืžื™ื™ื˜ ื“ื™ ื•ื•ืึธืจืงืคืœืึธื•ื• ื“ื•ืจืš ื™ืžืคึผืœืึทืžืขื ื™ื ื’ ืึท ืคื•ืœ ืกื™ / ืกื™ ืฆื™ืงืœ. ื‘ื•ื™ืขืŸ, ื˜ืขืกื˜ื™ื ื’ ืื•ืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ ืงืขื ืขืŸ ื–ื™ื™ืŸ ื˜ืจื™ื’ืขืจื“ ื“ื•ืจืš ืคืึทืจืฉื™ื“ืŸ ื’ืขืฉืขืขื ื™ืฉืŸ: ืคึผื•ืฉื™ื ื’ ืงืึธื“, ืงืจื™ื™ื™ื˜ื™ื ื’ ืึท ืžืขืœื“ื•ื ื’ ืึธื“ืขืจ ื™ืฉื•ื–. ื“ื™ ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืื™ื– ืœืขื’ืึทืžืจืข ืคืจื™ื™ ืคึฟืึทืจ ืฆื™ื‘ื•ืจ ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ื–.

ืื™ืŸ ื“ืขื ืึธืคึผื˜ื™ื™ืœื•ื ื’, ืื™ืš ื•ื•ืขื˜ ื•ื•ื™ื™ึทื–ืŸ ืื™ืจ ื•ื•ื™ ืฆื• ืฉื˜ืขืœืŸ ืึทืจื•ื™ืฃ ื“ื™ ื‘ื•ื™ืขืŸ ืื•ืŸ ืฉื˜ื•ืคึผืŸ ืคื•ืŸ ืงืึธื“ ืื•ืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ ืฆื• ื“ื™ Sonatype ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ื•ื•ืขืŸ ืจื™ืœื™ืกื™ื ื’ ืึท ืžืขืœื“ื•ื ื’, ื•ื•ื™ ื’ืขื–ื•ื ื˜ ื•ื•ื™ ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืกื™ืงืจื™ืฅ.

ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืกื™ืงืจื™ืฅ

ืคึฟืึทืจ ืึธื˜ืึทืžืึทื˜ื™ืง ืคึฟืึทืจื–ืึทืžืœื•ื ื’ ืื•ืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜, ืžื™ืจ ื•ื•ืขืœืŸ ื“ืึทืจืคึฟืŸ ืึท ื ื•ืžืขืจ ืคื•ืŸ ืกื•ื“ ื•ื•ืึทืœื•ืขืก, ืึทื–ืึท ื•ื•ื™ ื“ื™ ืฉืœื™ืกืœ ืฉื™ื™ึทืŸ, ื“ื™ ืคึผืึทืจืึธืœ ื•ื•ืึธืก ืžื™ืจ ืึทืจื™ื™ึทืŸ ื•ื•ืขืŸ ื“ื–ืฉืขื ืขืจื™ื™ื˜ื™ื ื’ ื“ื™ ืฉืœื™ืกืœ, ื“ื™ PGP ืฉืœื™ืกืœ ื–ื™ืš, ืื•ืŸ ื“ื™ ืœืึธื’ื™ืŸ / ืคึผืึทืจืึธืœ ืคึฟืึทืจ ืกืึธื ืึทื˜ื™ืคึผืข. ืื™ืจ ืงืขื ืขืŸ ืฉื˜ืขืœืŸ ื–ื™ื™ ืื™ืŸ ืึท ืกืคึผืขืฆื™ืขืœ ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืื™ืŸ ื“ื™ ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™ ืกืขื˜ื˜ื™ื ื’ืก:

ื ื™ืฆืŸ Gradle ืื•ืŸ Github ืึทืงืฉืึทื ื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ Java Project ืฆื• Sonatype Maven Central Repository

ืžื™ืจ ืฉื˜ืขืœืŸ ื“ื™ ืคืืœื’ืขื ื“ืข ื•ื•ืขืจื™ืึทื‘ืึทืœื–:

  • SONATYPE_USERNAME / SONATYPE_PASSWORD - ืœืึธื’ื™ืŸ / ืคึผืึทืจืึธืœ ื•ื•ืึธืก ืžื™ืจ ืึทืจื™ื™ึทืŸ ื•ื•ืขืŸ ืจืขื“ื–ืฉื™ืกื˜ืขืจื™ื ื’ ืžื™ื˜ Sonatype
  • SIGNING_KEYID / SIGNING_PASSWORD - PGP ืฉืœื™ืกืœ ืฉื™ื™ึทืŸ ืื•ืŸ ืคึผืึทืจืึธืœ ื‘ืึทืฉื˜ื™ืžื˜ ื‘ืขืฉืึทืก ื“ื–ืฉืขื ืขืจื™ื™ืฉืึทืŸ.

ืื™ืš ื•ื•ืึธืœื˜ ื•ื•ื™ ืฆื• ื•ื•ื•ื™ื ืขืŸ ืื•ื™ืฃ ื“ื™ GPG_KEY_CONTENTS ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง ืื™ืŸ ืžืขืจ ื“ืขื˜ืึทืœ. ื“ืขืจ ืคืึทืงื˜ ืื™ื– ืึทื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ ืžื™ืจ ื“ืึทืจืคึฟืŸ ืึท ืคึผืจื™ื•ื•ืึทื˜ ืคึผื’ืคึผ ืฉืœื™ืกืœ. ืื™ืŸ ืกื“ืจ ืฆื• ืฉื˜ืขืœืŸ ืขืก ืื™ืŸ ืกื™ืงืจื™ืฅ, ืื™ืš ื’ืขื•ื•ื™ื™ื ื˜ ืœื™ืžืขื“ ืื•ืŸ ื“ืขืจืฆื• ื”ืื˜ ืึท ื ื•ืžืขืจ ืคื•ืŸ ืึทืงืฉืึทื ื–.

  • ืœืึธืžื™ืจ ืขื ืงืจื™ืคึผื˜ ืื•ื ื“ื–ืขืจ ืฉืœื™ืกืœ ื ื™ืฆืŸ gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgื“ื•ืจืš ืึทืจื™ื™ึทืŸ ื“ื™ ืคึผืึทืจืึธืœ. ืขืก ื–ืึธืœ ื–ื™ื™ืŸ ื’ืขืฉื˜ืขืœื˜ ืื™ืŸ ืึท ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง: SECRET_PASSPHRASE
  • ืœืึธืžื™ืจ ื’ืขืจ ื“ื™ ืจื™ื–ืึทืœื˜ื™ื ื’ ื™ื ืงืจื™ืคึผื˜ื™ื“ ืฉืœื™ืกืœ ืื™ืŸ ื˜ืขืงืกื˜ ืคืึธืจืขื ื ื™ืฆืŸ base64: base64 9B695056.gpg.gpg > 9B695056.txt. ืžื™ืจ ืฉื˜ืขืœืŸ ื“ืขื ืื™ื ื”ืึทืœื˜ ืื™ืŸ ื“ื™ ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง: GPG_KEY_CONTENTS.

ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืึท ื‘ื•ื™ืขืŸ ื•ื•ืขืŸ ืคึผื•ืฉื™ื ื’ ืงืึธื“ ืื•ืŸ ืงืจื™ื™ื™ื˜ื™ื ื’ ืึท PR

ืขืจืฉื˜ืขืจ ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉืึทืคึฟืŸ ืึท ื˜ืขืงืข ืื™ืŸ ื“ืขืจ ื•ื•ืึธืจืฆืœ ืคื•ืŸ ื“ื™ื™ืŸ ืคึผืจื•ื™ืขืงื˜: .github/workflows.

ืฆื™ื™ื›ืŸ ื“ื™ ื˜ืขืงืข ืื™ืŸ ืขืก, ืœืžืฉืœ, gradle-ci-build.yml ืžื™ื˜ ื“ื™ ืคืืœื’ืขื ื“ืข ืื™ื ื”ืึทืœื˜:

name: build

on:
  push:
    branches:
      - master
      - dev
      - testing
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 8
        uses: actions/setup-java@v1
        with:
          java-version: 8

      - name: Build with Gradle
        uses: eskatos/gradle-command-action@v1
        with:
          gradle-version: current
          arguments: build -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}

ื“ืขื ื•ื•ืึธืจืงืคืœืึธื•ื• ื•ื•ืขื˜ ื–ื™ื™ืŸ ืขืงืกืึทืงื™ื•ื˜ืึทื“ ื•ื•ืขืŸ ืคึผื•ืฉื™ื ื’ ืฆื• ืฆื•ื•ื™ื™ื’ืŸ master, dev ะธ testing, ืื•ื™ืš ื•ื•ืขืŸ ืงืจื™ื™ื™ื˜ื™ื ื’ ืฆื™ืขืŸ ืจื™ืงื•ื•ืขืก.

ื“ื™ ื“ื–ืฉืึธื‘ืก ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ื“ื™ ืกื˜ืขืคึผืก ื•ื•ืึธืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ืขืงืกืึทืงื™ื•ื˜ืึทื“ ื‘ืื–ื™ืจื˜ ืื•ื™ืฃ ื“ื™ ืกืคึผืขืกื™ืคื™ืขื“ ื’ืขืฉืขืขื ื™ืฉืŸ. ืื™ืŸ ื“ืขื ืคืึทืœ, ืžื™ืจ ื•ื•ืขืœืŸ ื‘ื•ื™ืขืŸ ืื•ื™ืฃ ื“ื™ ืœืขืฆื˜ืข ื•ื•ืขืจืกื™ืข ืคื•ืŸ โ€‹โ€‹โ€‹โ€‹ื•ื‘ื•ื ื˜ื•, ื ื•ืฆืŸ Java 8 ืื•ืŸ ืื•ื™ืš ื ื•ืฆืŸ ืึท ืคึผืœื•ื’ื™ืŸ ืคึฟืึทืจ Gradle eskatos/gradle-command-action@v1, ื•ื•ืึธืก, ื ื™ืฆืŸ ื“ื™ ืœืขืฆื˜ ื•ื•ืขืจืกื™ืข ืคื•ืŸ โ€‹โ€‹ื“ื™ ืงืึทืœืขืงื˜ืขืจ, ื•ื•ืขื˜ ืœื•ื™ืคืŸ ื“ื™ ืงืึทืžืึทื ื“ื– ืกืคึผืขืกื™ืคื™ืขื“ ืื™ืŸ arguments. ื•ื•ืขืจื™ืึทื‘ืึทืœื– secrets.SONATYPE_USERNAME ะธ secrets.SONATYPE_PASSWORD ื“ืืก ื–ืขื ืขืŸ ื“ื™ ืกื™ืงืจื™ืฅ ื•ื•ืึธืก ืžื™ืจ ื’ืขืคืจืขื’ื˜ ืคืจื™ืขืจ.

ื“ื™ ื‘ื•ื™ืขืŸ ืจืขื–ื•ืœื˜ืึทื˜ืŸ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืฉืคื™ื’ืœื˜ ืื™ืŸ ื“ื™ ืึทืงื˜ื™ืึธื ืก ืงื•ื•ื™ื˜ืœ:

ื ื™ืฆืŸ Gradle ืื•ืŸ Github ืึทืงืฉืึทื ื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ Java Project ืฆื• Sonatype Maven Central Repository

ืึทื•ื˜ืึธื“ื™ืคึผืœื•ื™ ื•ื•ืขืŸ ืจื™ืœื™ืกื™ื ื’ ืึท ื ื™ื™ึทืข ืžืขืœื“ื•ื ื’

ืคึฟืึทืจ ืึทื•ื˜ืึธื“ื™ืคึผืœื•ื™ืžืึทื ื˜, ืžื™ืจ ื•ื•ืขืœืŸ ืฉืึทืคึฟืŸ ืึท ื‘ืึทื–ื•ื ื“ืขืจ ื•ื•ืึธืจืงืคืœืึธื•ื• ื˜ืขืงืข gradle-ci-publish.yml:

name: publish

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 8
        uses: actions/setup-java@v1
        with:
          java-version: 8

      - name: Prepare to publish
        run: |
          echo '${{secrets.GPG_KEY_CONTENTS}}' | base64 -d > publish_key.gpg
          gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.SECRET_PASSPHRASE}}" 
          --output secret.gpg publish_key.gpg
          echo "::set-env name=RELEASE_VERSION::${GITHUB_REF:11}"

      - name: Publish with Gradle
        uses: eskatos/gradle-command-action@v1
        with:
          gradle-version: current
          arguments: test publish -Psigning.secretKeyRingFile=secret.gpg -Psigning.keyId=${{secrets.SIGNING_KEYID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}

ื“ืขืจ ื˜ืขืงืข ืื™ื– ื›ึผืžืขื˜ ื™ื™ื“ืขื ื™ืงืึทืœ ืฆื• ื“ื™ ืคืจื™ืขืจื“ื™ืงืข ืึทื—ื•ืฅ ืคึฟืึทืจ ื“ื™ ื’ืขืฉืขืขื ื™ืฉ ืื™ืŸ ื•ื•ืึธืก ืขืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ื˜ืจื™ื’ืขืจื“. ืื™ืŸ ื“ืขื ืคืึทืœ, ื“ืึธืก ืื™ื– ื“ืขืจ ื’ืขืฉืขืขื ื™ืฉ ืคื•ืŸ ืงืจื™ื™ื™ื˜ื™ื ื’ ืึท ืงื•ื•ื™ื˜ืœ ืžื™ื˜ ืึท ื ืึธืžืขืŸ ืกื˜ืึทืจื˜ื™ื ื’ ืžื™ื˜ v.

ืื™ื™ื“ืขืจ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜, ืžื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืขืงืกื˜ืจืึทืงื˜ ื“ื™ PGP ืฉืœื™ืกืœ ืคื•ืŸ ื“ื™ ืกื™ืงืจื™ืฅ ืื•ืŸ ืฉื˜ืขืœืŸ ืขืก ืื™ืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜ ื•ื•ืึธืจืฆืœ, ืื•ืŸ ืื•ื™ืš ื“ืขืงืจื™ืคึผื˜ ืขืก. ื•ื•ื™ื™ึทื˜ืขืจ ืžื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉื˜ืขืœืŸ ืึท ืกืคึผืขืฆื™ืขืœ ืกื•ื•ื™ื•ื•ืข ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง RELEASE_VERSION ืฆื• ื•ื•ืึธืก ืžื™ืจ ืึธืคึผืฉื™ืงืŸ ืื™ืŸ gradle.build ื˜ืขืงืข. ืึทืœืข ื“ืขื ืื™ื– ื’ืขื˜ืืŸ ืื™ืŸ ื“ื™ ืึธืคึผื˜ื™ื™ืœื•ื ื’ Prepare to publish. ืžื™ืจ ื‘ืึทืงื•ืžืขืŸ ืื•ื ื“ื–ืขืจ ืฉืœื™ืกืœ ืคึฟื•ืŸ ื“ื™ GPG_KEY_CONTENTS ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง, ืื™ื‘ืขืจื–ืขืฆืŸ ืขืก ืื™ืŸ ืึท gpg ื˜ืขืงืข, ืื•ืŸ ื“ืขืงืจื™ืคึผื˜ ืขืก ื“ื•ืจืš ืคึผืœื™ื™ืกื™ื ื’ ืขืก ืื™ืŸ ื“ืขืจ ื˜ืขืงืข secret.gpg.

ื“ืขืจื ืึธืš ืžื™ืจ ืึทืงืกืขืก ื“ื™ ืกืคึผืขืฆื™ืขืœืข ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง GITHUB_REF, ืคึฟื•ืŸ ื•ื•ืึธืก ืžื™ืจ ืงืขื ืขืŸ ื‘ืึทืงื•ืžืขืŸ ื“ื™ ื•ื•ืขืจืกื™ืข ื•ื•ืึธืก ืžื™ืจ ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ื•ื•ืขืŸ ืงืจื™ื™ื™ื˜ื™ื ื’ ื“ื™ ืงื•ื•ื™ื˜ืœ. ื“ืขื ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง ืื™ืŸ ื“ืขื ืคืึทืœ ื”ืื˜ ื“ื™ ื•ื•ืขืจื˜ refs/tags/v0.0.2 ืคื•ืŸ ื•ื•ืึธืก ืžื™ืจ ืฉื ื™ื™ึทื“ืŸ ืึทื•ื•ืขืง ื“ื™ ืขืจืฉื˜ืขืจ 11 ืื•ืชื™ื•ืช ืฆื• ื‘ืึทืงื•ืžืขืŸ ื“ื™ ืกืคึผืขืฆื™ืคื™ืฉ ื•ื•ืขืจืกื™ืข. ื“ืขืจื ืึธืš, ืžื™ืจ ื ื•ืฆืŸ ื“ื™ ื ืึธืจืžืึทืœ Gradle ืงืึทืžืึทื ื“ื– ืคึฟืึทืจ ืืจื•ื™ืกื’ืขื‘ืŸ: test publish

ืงืึธื ื˜ืจืึธืœื™ืจื•ื ื’ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ ืจืขื–ื•ืœื˜ืึทื˜ืŸ ืื™ืŸ ื“ื™ Sonatype ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™

ื ืึธืš ืงืจื™ื™ื™ื˜ื™ื ื’ ื“ื™ ืžืขืœื“ื•ื ื’, ื“ื™ ื•ื•ืึธืจืงืคืœืึธื•ื• ื“ื™ืกืงืจื™ื™ื‘ื“ ืื™ืŸ ื“ื™ ืคืจื™ืขืจื“ื™ืงืข ืึธืคึผื˜ื™ื™ืœื•ื ื’ ื–ืึธืœ ืึธื ื”ื™ื™ื‘ืŸ. ืฆื• ื˜ืึธืŸ ื“ืึธืก, ืžื™ืจ ืžืึทื›ืŸ ืึท ืžืขืœื“ื•ื ื’:

ื ื™ืฆืŸ Gradle ืื•ืŸ Github ืึทืงืฉืึทื ื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ Java Project ืฆื• Sonatype Maven Central Repository

ืื™ืŸ ื“ืขื ืคืึทืœ, ื“ื™ ืงื•ื•ื™ื˜ืœ ื ืึธืžืขืŸ ืžื•ื–ืŸ ืึธื ื”ื™ื™ื‘ืŸ ืžื™ื˜ v. ืื•ื™ื‘, ื ืึธืš ื’ืขื‘ืŸ ืึท ืงืœื™ืง ืื•ื™ืฃ ืึทืจื•ื™ืกื’ืขื‘ืŸ ืžืขืœื“ื•ื ื’, ื“ื™ ื•ื•ืึธืจืงืคืœืึธื•ื• ืœื•ื™ืคื˜ ื”ืฆืœื—ื”, ืžื™ืจ ืงืขื ืขืŸ ื’ื™ื™ืŸ ืฆื• ืกืึธื ืึทื˜ื™ืคึผืข ื ืขืงืกื•ืก ืฆื• ืžืึทื›ืŸ ื–ื™ื›ืขืจ:

ื ื™ืฆืŸ Gradle ืื•ืŸ Github ืึทืงืฉืึทื ื– ืฆื• ืึทืจื•ื™ืกื’ืขื‘ืŸ Java Project ืฆื• Sonatype Maven Central Repository

ื“ืขืจ ืึทืจื˜ืึทืคืึทืงื˜ ืืจื•ื™ืก ืื™ืŸ ื“ื™ ืกื˜ืึทื’ื™ื ื’ ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™. ืขืก ื’ืœื™ื™ืš ืื•ื™ืก ืื™ืŸ ื“ื™ ืขืคึฟืŸ ืกื˜ืึทื˜ื•ืก, ืื•ืŸ ืขืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ืžืึทื ื™ื•ืึทืœื™ ื˜ืจืึทื ืกืคืขืจื“ ืฆื• ื“ื™ ื ืึธืขื ื˜ ืกื˜ืึทื˜ื•ืก ื“ื•ืจืš ื’ืขื‘ืŸ ืึท ืงืœื™ืง ืื•ื™ืฃ ื“ื™ ืงืึธืจืึทืกืคึผืึทื ื“ื™ื ื’ ืงื ืขืคึผืœ. ื ืึธืš ืงืึธื ื˜ืจืึธืœื™ืจื•ื ื’ ืึทื– ืึทืœืข ืจืขืงื•ื•ื™ืจืขืžืขื ืฅ ื–ืขื ืขืŸ ื‘ืื’ืขื’ื ื˜, ื“ื™ ืึทืจื˜ืึทืคืึทืงื˜ ื‘ืื•ื•ืขื’ื˜ ืฆื• ื ืึธืขื ื˜ ืกื˜ืึทื˜ื•ืก ืื•ืŸ ืื™ื– ื ื™ื˜ ืžืขืจ ื‘ื ื™ืžืฆื ืคึฟืึทืจ ืžืึธื“ื™ืคื™ืงืึทื˜ื™ืึธืŸ. ืื™ืŸ ื“ืขื ืคืึธืจืขื ืขืก ื•ื•ืขื˜ ื’ื™ื™ืŸ ืฆื• MavenCentral. ืื•ื™ื‘ ืึทืœืฅ ืื™ื– ื’ื•ื˜, ืื™ืจ ืงืขื ืขืŸ ื“ืจื™ืงืŸ ื“ืขื ืงื ืขืคึผืœ ืžืขืœื“ื•ื ื’, ืื•ืŸ ื“ืขืจ ืึทืจื˜ืึทืคืึทืงื˜ ื•ื•ืขื˜ ื’ื™ื™ืŸ ืฆื• ื“ื™ Sonatype ืจื™ืคึผืึทื–ืึทื˜ืึธืจื™.

ื›ึผื“ื™ ื“ื™ ืึทืจื˜ืึทืคืึทืงื˜ ื–ืึธืœ ื–ื™ื™ืŸ ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ืื™ืŸ MavenCentral, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ื‘ืขื˜ืŸ ืขืก ืื™ืŸ ื“ืขืจ ืึทืจื‘ืขื˜ ื•ื•ืึธืก ืžื™ืจ ื”ืึธื‘ืŸ ื‘ืืฉืืคืŸ ืื™ืŸ ื“ื™ ืึธื ื”ื™ื™ื‘. ืื™ืจ ื ืึธืจ ื“ืึทืจืคึฟืŸ ืฆื• ื˜ืึธืŸ ื“ืึธืก ืึทืžืึธืœ, ืึทื–ื•ื™ ืžื™ืจ ืึทืจื•ื™ืกื’ืขื‘ืŸ ืขืก ืคึฟืึทืจ ื“ื™ ืขืจืฉื˜ืขืจ ืžืึธืœ. ืขืก ืื™ื– ื ื™ื˜ ื“ืึทืจืคึฟืŸ ืฆื• ื˜ืึธืŸ ื“ืึธืก ื“ื™ ื•ื•ื™ื™ึทื˜ืขืจ ืžืึธืœ, ืึทืœืฅ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืกื™ื ื’ืงืจืึทื ื™ื™ื–ื“ ืื•ื™ื˜ืึธืžืึทื˜ื™ืฉ. ื–ื™ื™ ื”ืึธื‘ืŸ ื’ืขืฉื•ื•ื™ื ื“ ืกื™ื ื’ืงืจืึทื ื™ื™ื–ื“ ืคึฟืึทืจ ืžื™ืจ, ืึธื‘ืขืจ ืขืก ื’ืขื ื•ืžืขืŸ ื•ื•ืขื’ืŸ 5 ื˜ืขื’ ืคึฟืึทืจ ื“ื™ ืึทืจื˜ืึทืคืึทืงื˜ ืฆื• ื–ื™ื™ืŸ ื‘ืืจืขื›ื˜ื™ื’ื˜ ืื™ืŸ MavenCentral.

ืึทื– ืก ืึทืœืข, ืžื™ืจ ืืจื•ื™ืก ืื•ื ื“ื–ืขืจ ืึทืจื˜ืึทืคืึทืงื˜ ืื™ืŸ MavenCentral.

ื ื•ืฆื™ืง ืœื™ื ืงืก

ืžืงื•ืจ: www.habr.com