|
| 1 | +== The YAML workflow files vs. the `*.main.kts` files |
| 2 | + |
| 3 | +The YAML workflow files are generated from the `*.main.kts` files. |
| 4 | + |
| 5 | +These use the https://github.com/typesafegithub/github-workflows-kt[github-workflows-kt] |
| 6 | +Kotlin DSL library to conveniently and type-safely write GitHub Action workflow files. |
| 7 | + |
| 8 | +As there is no official built-in support in GitHub Actions yet until |
| 9 | +https://github.com/orgs/community/discussions/15904 is considered, the YAML files |
| 10 | +need to be generated manually. |
| 11 | + |
| 12 | +There is a safeguard check in all the generated files that this is not forgotten. |
| 13 | +Running a workflow where the according `*.main.kts` produces a different output will |
| 14 | +fail the execution. Additionally, the workflow that runs for pull requests checks |
| 15 | +the consistency of all the YAML files as not all are run for pull requests. |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +== Ways to generate the YAML workflow files |
| 20 | + |
| 21 | +There are multiple ways to generate the YAML files and all of them are fine, |
| 22 | +but be aware of the last one of the caveats below if you are not using the Gradle method: |
| 23 | + |
| 24 | +* If you are in a `sh` derivate like e.g. `bash` and Kotlin is installed and |
| 25 | + available in the `PATH`, you can just call the `*.main.kts` script like any |
| 26 | + other shell script: |
| 27 | ++ |
| 28 | +[source,bash] |
| 29 | +---- |
| 30 | +$ ./ci.main.kts |
| 31 | +---- |
| 32 | + |
| 33 | +* If Kotlin is installed somewhere you can call it with the `*.main.kts` script |
| 34 | + as argument: |
| 35 | ++ |
| 36 | +[source,bash] |
| 37 | +---- |
| 38 | +$ path/to/kotlin ci.main.kts |
| 39 | +---- |
| 40 | + |
| 41 | +* From the IDE you can create a run configuration that executes the `*.main.kts` script. |
| 42 | + |
| 43 | +* There is a Gradle task `preprocessWorkflows` that generates all YAML files from the |
| 44 | + according `*.main.kts` files. Additionally, there is also one task per workflow to |
| 45 | + only generate that one: |
| 46 | ++ |
| 47 | +[source,bash] |
| 48 | +---- |
| 49 | +$ ./gradlew preprocessCiWorkflow |
| 50 | +$ ./gradlew preprocessWorkflows |
| 51 | +---- |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +== Caveats |
| 56 | + |
| 57 | +There are currently three known caveats with the approach we follow. |
| 58 | + |
| 59 | +=== https://youtrack.jetbrains.com/issue/KTIJ-16532 |
| 60 | + |
| 61 | +If you navigate to a file in the dependencies, only a decompiled file is opened, |
| 62 | +even though the source JAR would be available. Also the quick documentation is missing. |
| 63 | + |
| 64 | +This can easily by mitigated by attaching the library to the normal project |
| 65 | +dependencies while having the need to navigate the source files or while editing them, |
| 66 | +which makes them properly viewable and documentation displayable in the editor. |
| 67 | + |
| 68 | +=== https://youtrack.jetbrains.com/issue/KTIJ-14580 |
| 69 | + |
| 70 | +We use `@file:Import` to reduce code duplication by having common code in a common file. |
| 71 | +Unfortunately, this triggers a Kotlin IntelliJ plugin bug where the imported file cannot |
| 72 | +be loaded properly and so the things supplied by it like dependencies or common functions |
| 73 | +are not available. This makes most of the workflow `*.main.kts` files red as hell in the |
| 74 | +IDE currently. |
| 75 | + |
| 76 | +To reduce risk for eye-cancer while reading the `*.main.kts` scripts or to be able to |
| 77 | +sanely edit them, temporarily add the `@file:DependsOn` from the imported file to the |
| 78 | +importing file and wait a second, then remove the line again once you are done. |
| 79 | + |
| 80 | +=== https://youtrack.jetbrains.com/issue/KT-42101 |
| 81 | + |
| 82 | +We use `@file:Import` to reduce code duplication by having common code in a common file. |
| 83 | +Unfortunately, this triggers a Kotlin bug where the compilation cache becomes confused |
| 84 | +if the imported file is changed without the importing file being changed too. |
| 85 | + |
| 86 | +If only the imported file is changed, it could happen that an old version is used, |
| 87 | +or it could also happen that classes added by a `@file:DependsOn` in the imported file |
| 88 | +are not available to the importing file. So if there was a change in the imported file, |
| 89 | +you either need to also change the importing file, or to properly execute the script, |
| 90 | +you need to delete the stale entry from the compilation cache which can be found here: |
| 91 | + |
| 92 | +- On Windows the default location is at `%LOCALAPPDATA%\main.kts.compiled.cache\`. |
| 93 | +- On Linux the default location is at `$XDG_CACHE_HOME/main.kts.compiled.cache/` or `~/.cache/main.kts.compiled.cache/`. |
| 94 | +- On macOS the default location is at `~/Library/Caches/main.kts.compiled.cache/`. |
| 95 | + |
| 96 | +Alternatively, you can also delete the whole cache directory. |
| 97 | + |
| 98 | +Another option is to disable the compilation cache for the execution by setting the |
| 99 | +environment variable `KOTLIN_MAIN_KTS_COMPILED_SCRIPTS_CACHE_DIR` or the system property |
| 100 | +`kotlin.main.kts.compiled.scripts.cache.dir` to an empty value, depending on the run |
| 101 | +method you chose. The Gradle tasks already do that, so when using the Gradle tasks you |
| 102 | +do not have this problem and it just works. |
0 commit comments