{"id":23779475,"url":"https://github.com/saagie/updatarium","last_synced_at":"2025-07-02T11:33:03.447Z","repository":{"id":43730960,"uuid":"230886417","full_name":"saagie/updatarium","owner":"saagie","description":"Updatarium : Update everything","archived":false,"fork":false,"pushed_at":"2023-09-11T14:14:38.000Z","size":484,"stargazers_count":14,"open_issues_count":22,"forks_count":6,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-06T15:54:41.466Z","etag":null,"topics":["bash","kubernetes","liquibase","mongodb","update"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saagie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-30T09:24:25.000Z","updated_at":"2022-02-21T10:43:45.000Z","dependencies_parsed_at":"2023-01-23T15:31:38.446Z","dependency_job_id":null,"html_url":"https://github.com/saagie/updatarium","commit_stats":null,"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/saagie/updatarium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saagie%2Fupdatarium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saagie%2Fupdatarium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saagie%2Fupdatarium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saagie%2Fupdatarium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saagie","download_url":"https://codeload.github.com/saagie/updatarium/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saagie%2Fupdatarium/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263130412,"owners_count":23418276,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","kubernetes","liquibase","mongodb","update"],"created_at":"2025-01-01T10:18:54.553Z","updated_at":"2025-07-02T11:33:03.380Z","avatar_url":"https://github.com/saagie.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](./doc/updatarium_full.png)\n# Updatarium\n\n[![Releases](https://img.shields.io/github/v/release/saagie/updatarium?color=blue)][release]\n[![Jitpack](https://img.shields.io/jitpack/v/github/saagie/updatarium)][jitpack]\n\n[![Issues](https://img.shields.io/github/issues-raw/saagie/updatarium?color=blue)][issues]\n[![License](https://img.shields.io/github/license/saagie/updatarium?color=lightgray)][license]\n[![Contributors](https://img.shields.io/github/contributors/saagie/updatarium?color=lightgray)][contributors]  \n\n[![workflow github](https://img.shields.io/github/workflow/status/saagie/updatarium/Build%20Master%20and%20Release)][build_master][![Coveralls github](https://img.shields.io/coveralls/github/saagie/updatarium)][coveralls]\n\n[release]: https://github.com/saagie/updatarium/releases\n[license]: https://github.com/saagie/updatarium/blob/master/LICENSE\n[contributors]: https://github.com/saagie/updatarium/graphs/contributors\n[issues]: https://github.com/saagie/updatarium/issues\n[jitpack]: https://jitpack.io/#saagie/updatarium\n[coveralls]: https://coveralls.io/github/saagie/updatarium\n[build_master]: https://github.com/saagie/updatarium/actions?query=workflow%3A%22Build+Master+and+Release%22\n### Goal\n\nThe goal of this project is to provide an easy way to execute actions only if it was never executed before. \nIt was inspired from liquibase mechanism, but instead of using XML files, we chose to use DSL and Kotlin script files.\n\n### How to use it / Usage\n\nThis project generates some libs, so you just have to add them in your `pom.xml` or `build.gradle.kts`: \n\n#### Maven\n\nIn your `pom.xml`:\n\nAdd JCenter maven repository\n \n```xml\n    \u003crepositories\u003e\n        \u003crepository\u003e\n            \u003csnapshots\u003e\n                \u003cenabled\u003efalse\u003c/enabled\u003e\n            \u003c/snapshots\u003e\n            \u003cid\u003ecentral\u003c/id\u003e\n            \u003cname\u003ejitpack-plugins\u003c/name\u003e\n            \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n        \u003c/repository\u003e\n    \u003c/repositories\u003e\n```\n\nAnd add our libs (core at least) replacing `updatarium.version` with the latest version\n\n```xml\n    \u003cdependencies\u003e\n        \u003cdependency\u003e\n            \u003cgroupId\u003eorg.jetbrains.kotlin\u003c/groupId\u003e\n            \u003cartifactId\u003ekotlin-stdlib\u003c/artifactId\u003e\n            \u003cversion\u003e${kotlin.version}\u003c/version\u003e\n        \u003c/dependency\u003e\n        \u003cdependency\u003e\n            \u003cgroupId\u003eio.saagie.updatarium\u003c/groupId\u003e\n            \u003cartifactId\u003ecore\u003c/artifactId\u003e\n            \u003cversion\u003e${updatarium.version}\u003c/version\u003e\n        \u003c/dependency\u003e\n    \u003c/dependencies\u003e\n```\n\nYou can also add some engines (example with `engine-httpclient`) or persist-engine\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.saagie.updatarium\u003c/groupId\u003e\n        \u003cartifactId\u003eengine-httpclient\u003c/artifactId\u003e\n        \u003cversion\u003e${updatarium.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.saagie.updatarium\u003c/groupId\u003e\n        \u003cartifactId\u003epersist-mongodb\u003c/artifactId\u003e\n        \u003cversion\u003e${updatarium.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n#### Gradle\n\nAdd JCenter maven repository\n\n```kotlin\nrepositories {\n    //...\n    jcenter()\n}\n```\n\n...\n\nAnd add our libs (core at least) replacing `LATEST_VERSION` with the latest version\n\n```kotlin\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\")) // Kotlin standard libs\n\n    implementation(\"io.saagie.updatarium:core:LATEST_VERSION\") // Updatarium Core library (mandatory)\n    \n    // Kotlin scripting (mandatory to use kts compilation)\n    implementation(kotlin(\"scripting-compiler-embeddable\")) \n    implementation(kotlin(\"script-util\"))\n}\n```\n\nYou can also add some engines (example with `engine-httpclient`) or persist-engine\n\n```kotlin\nimplementation(\"io.saagie.updatarium:engine-httpclient:LATEST_VERSION\")\nimplementation(\"io.saagie.updatarium:persist-mongodb:LATEST_VERSION\")\n```\n\n#### Running a changeLog\n\nYou need to create an Updatarium instance, then call the `executeChangeLog` function with a `Path` of your changeLog file (or a `Reader`): \n\n```kotlin\nUpdatarium().executeChangeLog(pathOfYourChangeLogFile)\n```\n\nYou can also use a persist-engine (to store executions and logs ... see below to know more about persist-engines):  \n```kotlin\nUpdatarium(MongodbPersistEngine()).executeChangeLog(pathOfYourChangeLogFile)\n```\n\n\n#### Running multiples changeLogs \n\nYou can also run some changeLogs, using this function `executeChangeLogs` (`resourcesDirectory` is a Path - needs to be a directory,\nand the second arguments is a regex pattern to select changeLogs files): \n\n```kotlin\nUpdatarium().executeChangeLogs(resourcesDirectory, \"changeLog(.*).kts\")\n```\n \n#### The tag system\n\nYou can add some tags into a changeSet like this : \n\n```kotlin\nchangeSet(id = \"ChangeSet-bash-1-1\", author = \"Bash\") {\n    tags = listOf(\"before\")\n    action {\n        (1..5).forEach {\n            logger.info { \"Hello $it!\" }\n        }\n    }\n}\n``` \n\nAnd you can `executeChangeLog`(s) with a list of tag. If none, no tag matching system is applied...\nIf you add a list of tags, all changeSets matched with at least one tag you use will be executed.  \n\nIn this example, `ChangeSet-bash-1-1` will be executed. \n\n ```kotlin\nUpdatarium().executeChangeLog(changeLog,listOf(\"before\",\"after\")) \n```\n\nIn this example, `ChangeSet-bash-1-1` will not be executed.\n\n```kotlin\nUpdatarium().executeChangeLog(changeLog,listOf(\"after\")) \n```\n\n#### Force the execution of a change set\nBy default, a changeSet can not be re-executed if it has already been run, based on the changeSet id.\n\n```kotlin\nchangeLog {\n    changeSet(id = \"ChangeSet-1\", author = \"author\") {\n        action {\n            logger.info { \"Hello world!\" }\n        }\n    }\n\n    // The following changeSet will not be executed again\n    changeSet(id = \"ChangeSet-1\", author = \"author\") {\n        action {\n            logger.info { \"Will not be executed\" }\n        }\n    }\n}\n```\n\nHowever, it is possible to override this default behaviour by using the force parameter on a specific changeSet:\n\n```kotlin\nchangeLog {\n    changeSet(id = \"ChangeSet-1\", author = \"author\") {\n        action {\n            logger.info { \"Hello world!\" }\n        }\n    }\n\n    // The following changeSet will be executed again\n    changeSet(id = \"ChangeSet-1\", author = \"author\") {\n        force = true\n        action {\n            logger.info { \"Hello world again!\" }\n        }\n    }\n}\n```\n\n#### PersistConfiguration\n\nYou can configure the persistEngine, using a `PersistConfiguration` like this : \n\n```kotlin\nval config = PersistConfig(\n            level = Level.INFO,\n            onSuccessStoreLogs = true,\n            onErrorStoreLogs = true\n        ) { event -\u003e event.message!! }\nUpdatarium(MongodbPersistEngine(config)).executeChangeLog(pathOfYourChangeLogFile)\n```\n\nA `PersistConfig` instance should have :\n \n - level : org.apache.logging.log4j.Level (the minimal log level captured)\n - onSuccessStoreLogs : boolean. At true, persistEngine will receive a list of logs when call the `unlock` function in case of success.\n - onErrorStoreLogs : boolean. At true, persistEngine will receive a list of logs when call the `unlock` function in case of failure.\n - layout : a lambda representing the transformation to applied to map a `InMemoryEvent` into a `String`\n \n### Architecture\n\n#### The concept of ChangeLogs and ChangeSets?\n\nA changeLog represent all changes you have to execute for a version, a date,...\n\nIn a changeLog, you can have one or more changeSets. \n\nEach changeSet represent a list of dependent changes to execute.\n\nOne example :\nfor a new release you need to update all customer documents in a MongoDb database by adding a new field, then call an HTTP endpoint to activate a feature. \nAnd for the same release, you should do some modifications in Kubernetes pods with no link with the customers documents modification.\nYou have 2 changeSets: \n - one for the customer documents and HTTP call\n - one for the Kubernetes modification  \n\nbecause they are no links between both, but you have a link between the MongoDb document update, and the HTTP call ...\nIf the MongoDb update failed, you should not execute the HTTP call.\n\nSo you'll have this : \n\n- ChangeLog\n   - ChangeSet1 \n     - action: update MongoDb\n     - action: HTTP call\n   - ChangeSet2\n     - action: Kubernetes modification\n \n#### Internal organization\n\nBy design, we decide to split all engines to have a light library.\n\n- ##### core\n\nThis project contains all the main code for Updatarium to run.\nIt contains the changeLog/changeSet model, and the mechanism for the execution and all necessary Interface (`Action` and `PersistEngine`)   \n\nTo have a running project, you have a basic implementation of Action with a lambda, and a basic persist implementation (without persistence ... That means all changeSet will be executed)\n\nYou have an entry point : the class `Updatarium` with these functions `executeChangeLog()`.   \n\n- ##### persist-*\n\nThese projects contain an implementation of a `PersistEngine`.\n\nFor the moment, only MongoDb is supported, but you can easily create your own `persist-XXX` project (see the CONTRIBUTING.md for more information) \n\n- ##### engine-*\n\nThese projects contain an implementation of an `Action`.\n\nFor the moment : \n- MongoDb\n- Bash\n- HttpClient\n- Kubernetes\nare supported, but you can easily create your own `engine-XXX` project (see the CONTRIBUTING.md for more information\n\n- ##### samples\n\nYou'll find in the sample directory some examples to use Updatarium.\n\n- ##### updatarium-cli\n\nA command line module to provide an all-in-one application a ship it into a Docker image ([saagie/updatarium](https://hub.docker.com/r/saagie/updatarium)))\n\n### Credits\nLogo : \n - Made by [@pierreLeresteux](https://github.com/pierreLeresteux)\n - Rocket : Created by [Gregor Cresnar](https://thenounproject.com/grega.cresnar/) from noun project \n - Font : Moon of Jupyter by Frederik (fthafm.com) [https://www.dafont.com/moon-of-jupiter.font](https://www.dafont.com/profile.php?user=982187) \n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaagie%2Fupdatarium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaagie%2Fupdatarium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaagie%2Fupdatarium/lists"}