Package and Publish Your Standards
Now that you’ve created reusable configuration components, let’s package them so they can be shared across projects and teams. This tutorial shows how to publish your ScheduledGreeting workflow and StandardRepoFiles as a versioned Typeflows package by structuring them for distribution, configuring build files for publishing, and making them available through artifact repositories.
Prerequisites
- Completion of the Writing Reusable Configuration tutorial
- Familiarity with your language’s package manager (Gradle/Maven)
- Access to an artifact repository (GitHub Packages, Maven Central, or local repository)
Step 1: Prepare Your Package
First, let’s move your configurations from the Typeflows export structure into a standard library structure. This transforms them from something that generates files for this repository into a reusable library that other repositories can consume:
Better Experience in Landscape Mode
The code examples look much better when viewed horizontally. Please rotate your device for the best experience!
Or view on a larger screen to see the code!
class ScheduledGreeting(
private val name: String,
private val cronSchedule: Cron,
private val message: String
) : Builder<Workflow> {
override fun build() = Workflow(name) {
on += Schedule {
cron += cronSchedule
}
jobs += Job("greet", UBUNTU_LATEST) {
steps += RunCommand("echo '$message'")
}
}
}
Additionally, let’s add a StandardRepoFiles configuration that packages common repository files that we don’t want to represent as code:
Better Experience in Landscape Mode
The code examples look much better when viewed horizontally. Please rotate your device for the best experience!
Or view on a larger screen to see the code!
class StandardRepoFiles : Builder<TypeflowsResources> {
override fun build() = TypeflowsResources.of(StandardRepoFiles::class.java)
}
And the corresponding resource file that will be packaged:
Better Experience in Landscape Mode
The code examples look much better when viewed horizontally. Please rotate your device for the best experience!
Or view on a larger screen to see the code!
MIT License
Copyright (c) 2024 Example Corp
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.Notice the structural changes:
From Typeflows Export Structure to Standard Package Structure: We’re moving from the Typeflows-specific layout to the standard package structure for your language, following its established conventions for publishable libraries.
Key Aspects:
- Standard Package Layout: Using your language’s conventions for publishable libraries
- Package Namespace: The configurations use a clear namespace following your language’s conventions, making it clear where the code comes from when others import it
- Builder Pattern: Both
ScheduledGreetingandStandardRepoFilesimplementBuilder<T>, which is the standard pattern for creating reusable Typeflows components - Resource Packaging:
TypeflowsResourcespackages files from the associated resource directory into your configuration library
The Builder pattern is crucial because it allows other Typeflows repositories to instantiate your configurations with different parameters while maintaining type safety.
Why the Builder Pattern?
Typeflows treats configurations as data. Your ScheduledGreeting doesn’t become a workflow - it produces workflow data.
This separation means:
- Builders contain logic and parameters
- Configurations are pure data structures
- One builder creates many configuration variations
- Resources are packaged as reusable file collections
This is the “Typeflows Way” - your classes are factories that build configurations, not configurations themselves.
Step 2: Configure Publishing
Next, add build configuration to make your package publishable. This includes metadata like name, version, and dependencies:
Better Experience in Landscape Mode
The code examples look much better when viewed horizontally. Please rotate your device for the best experience!
Or view on a larger screen to see the code!
plugins {
kotlin("jvm")
id("maven-publish")
}
group = "com.example"
artifact = "typeflows-standards"
version = "1.0.0"
repositories {
mavenCentral()
}
dependencies {
implementation("io.typeflows:typeflows-github:1.0.0")
}
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
pom {
name.set("Typeflows Standards")
description.set("Reusable Typeflows components for team standardisation")
url.set("https://github.com/example/typeflows-standards")
}
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/example/typeflows-standards")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}
Key points in the configuration:
- Package Coordinates: The unique identifier for your package in the repository
- Version: Start with
1.0.0following semantic versioning - Typeflows Dependency: Your package depends on Typeflows core libraries
- Publishing Configuration: Specifies where to publish and with what credentials
Step 3: Build and Publish
Now you can build and publish your package:
Better Experience in Landscape Mode
The code examples look much better when viewed horizontally. Please rotate your device for the best experience!
Or view on a larger screen to see the code!
# Build and publish to repository
./gradlew build publish
# Output:
# > Task :compileKotlin
# > Task :compileJava NO-SOURCE
# > Task :processResources NO-SOURCE
# > Task :classes
# > Task :jar
# > Task :generateMetadataFileForMavenPublication
# > Task :generatePomFileForMavenPublication
# > Task :publishMavenPublicationToGitHubPackagesRepository
# > Task :publish
#
# BUILD SUCCESSFUL in 3sThe build process creates a package artifact containing your ScheduledGreeting class, StandardRepoFiles class, and the packaged resource files, and the publish step uploads it to your configured repository.
Conclusion
Your ScheduledGreeting and StandardRepoFiles are now shareable packages, demonstrating the “Share” phase of the Typeflows Cycle.
Key capabilities of your package:
- Type-safe instantiation via Builder pattern
- Resource packaging for reusable file collections
- Semantic versioning for controlled updates
- Standard dependency management