-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
1,100 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
--- | ||
id: ci-workflow | ||
|
||
sidebar_label: CI Workflow | ||
|
||
title: CI Workflow | ||
--- | ||
|
||
ModuleCheck will automatically fix most issues. Most CI platforms are able to commit changes, and | ||
automatically cancel out-of-date jobs when the branch has been updated. This tooling can be used to | ||
apply ModuleCheck's automatic fixes (if any) as part of a CI run, then cancel and start a new run. | ||
This is similar to a git pre-commit hook, except the work is delegated to a build server. | ||
|
||
### Using CI over git hooks | ||
|
||
The traditional method for applying changes automatically is with a git hook, such as pre-commit or | ||
pre-push. But if the task-to-be-automated has a runtime of more than a few seconds, this is a poor | ||
developer experience. With a CI task, the execution is done automatically and asynchronously, while | ||
the developer is already moving on to something else. | ||
|
||
A git hook also technically doesn't guarantee that a task is executed before code is checked in to a | ||
main branch, since there's no guarantee that a hook is enabled. With CI, the task will output a | ||
status check. If a branch protection rule is enabled, that status check can be required. This will | ||
then guarantee that the task has run (successfully) before any code is checked in to the protected | ||
branch. | ||
|
||
### Example Flow chart | ||
|
||
This is a simplified flowchart of how I would run ModuleCheck with unit tests in CI. The | ||
cancellation, test, and ModuleCheck jobs run in parallel on three different runners. This is an | ||
"optimistic" workflow, in that it assumes that the `modulecheck` task will not generate changes | ||
which would trigger a restart. | ||
|
||
```mermaid | ||
flowchart TB | ||
Start(CI Start):::good --> mGraph | ||
Start --> tGraph | ||
Start --> cGraph | ||
subgraph mGraph [runner 1] | ||
direction TB | ||
ModuleCheck(./gradlew moduleCheckAuto):::code --> ChangesModuleCheck | ||
ChangesModuleCheck{Graph changes?} --- yesM[yes]:::lineLabel --> CommitModuleCheck(Commit changes and push):::stop | ||
ChangesModuleCheck --- noM[no]:::lineLabel --> EndModuleCheck("#10003;"):::good | ||
end | ||
subgraph tGraph [runner 2] | ||
direction TB | ||
Tests(./gradlew test):::code --> EndTests("#10003;"):::good | ||
end | ||
subgraph cGraph [runner 3] | ||
direction TB | ||
Cancel(Cancel previous CI run):::code | ||
end | ||
style tGraph fill:#EEE,stroke:#000 | ||
style cGraph fill:#EEE,stroke:#000 | ||
style mGraph fill:#EEE,stroke:#000 | ||
classDef good fill:#0B0,stroke:#000 | ||
classDef stop fill:#E33,stroke:#000 | ||
classDef code fill:#AAA,stroke:#000 | ||
style ChangesModuleCheck fill:#CD1,stroke:#000 | ||
classDef lineLabel fill:#FFF,stroke:#FFF | ||
``` | ||
|
||
### Example GitHub Action | ||
|
||
Here's an Action which will run ModuleCheck, then commit any changes | ||
using [Stefanzweifel's auto-commit](https://github.com/stefanzweifel/git-auto-commit-action). This | ||
requires a personal access token secret, or the commit step will fail. | ||
|
||
```yaml title=.github/workflows.module-check.yml | ||
name: ModuleCheck | ||
|
||
on: | ||
pull_request: | ||
|
||
jobs: | ||
|
||
cancel-stale-jobs: | ||
name: Cancel stale jobs | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
# cancel previous jobs | ||
- name: Cancel Previous Runs | ||
uses: styfle/[email protected] | ||
env: | ||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' | ||
|
||
ModuleCheck: | ||
name: ModuleCheck | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
with: | ||
ref: ${{ github.event.pull_request.head.ref }} | ||
# Must use a personal access token in order to commit changes | ||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
fetch-depth: 0 | ||
|
||
- name: Set up JDK | ||
uses : actions/setup-java@v2 | ||
with : | ||
distribution : 'temurin' | ||
java-version : '11' | ||
|
||
# performs tree-shaking on the Gradle dependency graph | ||
- name: modulecheck | ||
run: ./gradlew moduleCheckAuto --no-daemon | ||
|
||
# If ModuleCheck generated changes, commit and push those changes. | ||
# If there are no changes, then this is a no-op. | ||
- name: commit changes | ||
uses: stefanzweifel/git-auto-commit-action@v4 | ||
with: | ||
commit_message: Apply ModuleCheck changes | ||
commit_options: '--no-verify --signoff' | ||
|
||
tests: | ||
name: Unit tests | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
with: | ||
ref: ${{ github.event.pull_request.head.ref }} | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
fetch-depth: 0 | ||
|
||
- name: Set up JDK | ||
uses : actions/setup-java@v2 | ||
with : | ||
distribution : 'temurin' | ||
java-version : '14' | ||
|
||
- name: all tests | ||
run: ./gradlew test --no-daemon | ||
``` |
170 changes: 170 additions & 0 deletions
170
website/versioned_docs/version-0.12.4/configuration.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
--- | ||
id: configuration | ||
sidebar_label: Configuration | ||
--- | ||
|
||
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; | ||
|
||
<Tabs groupId="language" | ||
defaultValue="Kotlin" | ||
values={[ | ||
{label: 'Kotlin', value: 'Kotlin'}, {label: 'Groovy', value: 'Groovy'}, | ||
]}> | ||
|
||
<TabItem value="Kotlin"> | ||
|
||
``` kotlin title="root/build.gradle.kts" | ||
plugins { | ||
id("com.rickbusarow.module-check") version "0.13.0-SNAPSHOT" | ||
} | ||
|
||
moduleCheck { | ||
|
||
deleteUnused = true // default is false | ||
|
||
checks { | ||
overShotDependency = true // default is true | ||
redundantDependency = false // default is false | ||
unusedDependency = true // default is true | ||
mustBeApi = true // default is true | ||
inheritedDependency = true // default is true | ||
sortDependencies = false // default is false | ||
sortPlugins = false // default is false | ||
unusedKapt = true // default is true | ||
anvilFactoryGeneration = true // default is true | ||
disableAndroidResources = false // default is false | ||
disableViewBinding = false // default is false | ||
unusedKotlinAndroidExtensions = false // default is false | ||
depths = false // default is false | ||
} | ||
|
||
// allow these modules to be declared as dependency anywhere, | ||
// regardless of whether they're used | ||
ignoreUnusedFinding = setOf(":test:core-jvm", ":test:core-android") | ||
|
||
// do not check the dependencies of these modules. | ||
// in this case, :app could declare any module it wants without issue | ||
doNotCheck = setOf(":app") | ||
|
||
additionalCodeGenerators = listOf( | ||
modulecheck.config.CodeGeneratorBinding.AnnotationProcessor( | ||
name = "My Processor", | ||
generatorMavenCoordinates = "my-project.codegen:processor", | ||
annotationNames = listOf( | ||
"myproject.MyInject", | ||
"myproject.MyInject.Factory", | ||
"myproject.MyInjectParam", | ||
"myproject.MyInjectModule" | ||
) | ||
) | ||
) | ||
|
||
reports { | ||
checkstyle { | ||
enabled = true // default is false | ||
outputPath = "${project.buildDir}/reports/modulecheck/checkstyle.xml" | ||
} | ||
sarif { | ||
enabled = true // default is false | ||
outputPath = "${project.buildDir}/reports/modulecheck/modulecheck.sarif" | ||
} | ||
depths { | ||
enabled = true // default is false | ||
outputPath = "${project.buildDir}/reports/modulecheck/depths.txt" | ||
} | ||
graphs { | ||
enabled = true // default is false | ||
// The root directory of all generated graphs. If set, directories will be created | ||
// for each module, mirroring the structure of the project. If this property is null, | ||
// graphs will be created in the `build/reports/modulecheck/graphs/` relative | ||
// directory of each project. | ||
outputDir = "${project.buildDir}/reports/modulecheck/graphs" | ||
} | ||
text { | ||
enabled = true // default is false | ||
outputPath = "${project.buildDir}/reports/modulecheck/report.txt" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
</TabItem> | ||
|
||
<TabItem value="Groovy"> | ||
|
||
``` groovy title="root/build.gradle" | ||
plugins { | ||
id 'com.rickbusarow.module-check' version '0.13.0-SNAPSHOT' | ||
} | ||
moduleCheck { | ||
deleteUnused = true // default is false | ||
checks { | ||
overShotDependency = true // default is true | ||
redundantDependency = false // default is false | ||
unusedDependency = true // default is true | ||
mustBeApi = true // default is true | ||
inheritedDependency = true // default is true | ||
sortDependencies = false // default is false | ||
sortPlugins = false // default is false | ||
unusedKapt = true // default is true | ||
anvilFactoryGeneration = true // default is true | ||
disableAndroidResources = false // default is false | ||
disableViewBinding = false // default is false | ||
unusedKotlinAndroidExtensions = false // default is false | ||
depths = false // default is false | ||
} | ||
// allow these modules to be declared as dependency anywhere, | ||
// regardless of whether they're used | ||
ignoreUnusedFinding = [':test:core-jvm', ':test:core-android'] | ||
// do not check the dependencies of these modules. | ||
// in this case, :app could declare any module it wants without issue | ||
doNotCheck = [':app'] | ||
additionalCodeGenerators = [ | ||
new modulecheck.config.CodeGeneratorBinding.AnnotationProcessor( | ||
'My Processor', | ||
'my-project.codegen:processor', | ||
[ | ||
"myproject.MyInject", | ||
"myproject.MyInject.Factory", | ||
"myproject.MyInjectParam", | ||
"myproject.MyInjectModule" | ||
] | ||
) | ||
] | ||
reports { | ||
checkstyle { | ||
it.enabled = true // default is false | ||
it.outputPath = "${project.buildDir}/reports/modulecheck/checkstyle.xml" | ||
} | ||
sarif { | ||
it.enabled = true // default is false | ||
it.outputPath = "${project.buildDir}/reports/modulecheck/modulecheck.sarif" | ||
} | ||
depths { | ||
it.enabled = true // default is false | ||
it.outputPath = "${project.buildDir}/reports/modulecheck/depths.txt" | ||
} | ||
graphs { | ||
it.enabled = true // default is false | ||
// The root directory of all generated graphs. If set, directories will be created | ||
// for each module, mirroring the structure of the project. If this property is null, | ||
// graphs will be created in the `build/reports/modulecheck/graphs/` relative | ||
// directory of each project. | ||
it.outputDir = "${project.buildDir}/reports/modulecheck/graphs" | ||
} | ||
text { | ||
it.enabled = true // default is false | ||
it.outputPath = "${project.buildDir}/reports/modulecheck/report.txt" | ||
} | ||
} | ||
} | ||
``` | ||
</TabItem> | ||
</Tabs> |
Oops, something went wrong.