From e2ca954499e92751b11e5b1abfc2aac2fba79f12 Mon Sep 17 00:00:00 2001 From: James Welch Date: Wed, 11 Sep 2024 15:57:34 +0100 Subject: [PATCH] GitHub Actions script with config for publishing and codenarc --- .github/workflows/gradle.yml | 144 ++++++++++ build.gradle | 14 + config/codenarc/codenarc.groovy | 452 ++++++++++++++++++++++++++++++++ 3 files changed, 610 insertions(+) create mode 100644 .github/workflows/gradle.yml create mode 100644 config/codenarc/codenarc.groovy diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..033f5ac --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,144 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle + +name: Java CI with Gradle + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + +permissions: + contents: read + actions: read + checks: write + security-events: write + +jobs: + build: + + runs-on: ubuntu-latest + + env: + GRADLE_OPTS: -Dorg.gradle.jvmargs="-XX:MaxMetaspaceSize=1g -Xmx1024m" + + services: + postgres: + image: postgres + env: + POSTGRES_USER: sandbox + POSTGRES_DB: sandbox + POSTGRES_PASSWORD: sandbox + options: >- + --health-cmd pg_isready + --health-interval 1s + --health-timeout 5s + --health-retries 50 + ports: + - 5432:5432 + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + cache-disabled: true + build-scan-publish: true + build-scan-terms-of-use-url: "https://gradle.com/terms-of-service" + build-scan-terms-of-use-agree: "yes" + + - name: Core gradle info + run: | + ./gradlew -v + ./gradlew jvmArgs sysProps + + - name: Grails info + run: | + ./grailsw -v + + - name: License header check + run: | + ./gradlew license + +# - name: Unit Tests +# run: ./gradlew test --no-daemon --stacktrace -Duser.language=en -Duser.country=GB + +# - name: Unit Test Report +# uses: dorny/test-reporter@v1 +# if: success() || failure() +# with: +# name: Unit Test Results +# path: '**/build/test-results/**/*.xml' +# reporter: java-junit +# list-tests: 'failed' + + - name: Integration Tests + run: | + ./gradlew -Dgradle.integrationTest=true integrationTest + + - name: Integration Test Report + uses: dorny/test-reporter@v1 + if: success() || failure() + with: + name: Integration Test Results + path: '**/build/test-results/integrationTest/*.xml' + reporter: java-junit + list-tests: 'failed' + + - name: MegaLinter + uses: oxsecurity/megalinter/flavors/ci_light@v8 + env: + # All available variables are described in documentation + # https://megalinter.io/configuration/ + VALIDATE_ALL_CODEBASE: true + ENABLE_LINTERS: GROOVY_NPM_GROOVY_LINT + LINTER_RULES_PATH: 'config/codenarc' + DISABLE_ERRORS: true #Flag to have the linter complete with exit code 0 even if errors were detected. + SARIF_REPORTER: true + + # This is currently too big for the security tab +# - name: Upload MegaLinter scan results to GitHub Security tab +# if: success() || failure() +# uses: github/codeql-action/upload-sarif@v2 +# with: +# sarif_file: 'megalinter-reports/megalinter-report.sarif' + + + # Upload MegaLinter artifacts + - name: Archive lint reports + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log + + - name: Publish Snapshot to Mauro Snapshot Repository + if: success() && github.ref == 'refs/heads/develop' + run: | + ./gradlew --stacktrace -PMauroSnapshotRepositoryUsername=${{secrets.MAURO_SNAPSHOT_REPOSITORY_USERNAME}} -PMauroSnapshotRepositoryPassword=${{secrets.MAURO_SNAPSHOT_REPOSITORY_PASSWORD}} publishAllPublicationsToMauroSnapshotRepositoryRepository + + + - name: Send a stream message + if: success() || failure() + uses: zulip/github-actions-zulip/send-message@v1 + with: + api-key: ${{ secrets.ZULIP_API_KEY }} + email: "githubactionsbot-bot@maurodatamapper.zulipchat.com" + organization-url: "https://maurodatamapper.zulipchat.com" + to: "build/github-actions" + type: "stream" + topic: "${{github.repository}}" + content: "${{ job.status == 'success' && ':check_mark:' || ':cross_mark:' }} ${{github.repository}} : **${{github.ref}}**\nGitHub Actions build result: **${{ job.status }}**\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" \ No newline at end of file diff --git a/build.gradle b/build.gradle index 39529d8..953fff0 100644 --- a/build.gradle +++ b/build.gradle @@ -115,4 +115,18 @@ grails { } } +publishing { + repositories { + maven { + name = "MauroSnapshotRepository" + url = "https://mauro-repository.com/libs-snapshot-local" + credentials(PasswordCredentials) + authentication { + basic(BasicAuthentication) + } + } + } +} + + apply from: 'dependencies.gradle' diff --git a/config/codenarc/codenarc.groovy b/config/codenarc/codenarc.groovy new file mode 100644 index 0000000..0b25690 --- /dev/null +++ b/config/codenarc/codenarc.groovy @@ -0,0 +1,452 @@ +ruleset { + + description ''' + A Sample Groovy RuleSet containing all CodeNarc Rules, grouped by category. + You can use this as a template for your own custom RuleSet. + Just delete the rules that you don't want to include. + ''' + + // rulesets/basic.xml + AssertWithinFinallyBlock + AssignmentInConditional + BigDecimalInstantiation + BitwiseOperatorInConditional + BooleanGetBoolean + BrokenNullCheck + BrokenOddnessCheck + ClassForName + ComparisonOfTwoConstants + ComparisonWithSelf + ConstantAssertExpression + ConstantIfExpression + ConstantTernaryExpression + DeadCode + DoubleNegative + DuplicateCaseStatement + DuplicateMapKey + DuplicateSetValue + EmptyCatchBlock + EmptyClass + EmptyElseBlock + EmptyFinallyBlock + EmptyForStatement + EmptyIfStatement + EmptyInstanceInitializer + EmptyMethod + EmptyStaticInitializer + EmptySwitchStatement + EmptySynchronizedStatement + EmptyTryBlock + EmptyWhileStatement + EqualsAndHashCode + EqualsOverloaded + ExplicitGarbageCollection + ForLoopShouldBeWhileLoop + HardCodedWindowsFileSeparator + HardCodedWindowsRootDirectory + IntegerGetInteger + MultipleUnaryOperators + ParameterAssignmentInFilterClosure + RandomDoubleCoercedToZero + RemoveAllOnSelf + ReturnFromFinallyBlock + ThrowExceptionFromFinallyBlock + + // rulesets/braces.xml + ElseBlockBraces + ForStatementBraces + IfStatementBraces + WhileStatementBraces + + // rulesets/comments.xml + ClassJavadoc + JavadocConsecutiveEmptyLines + JavadocEmptyAuthorTag + JavadocEmptyExceptionTag + JavadocEmptyFirstLine + JavadocEmptyLastLine + JavadocEmptyParamTag + JavadocEmptyReturnTag + JavadocEmptySeeTag + JavadocEmptySinceTag + JavadocEmptyThrowsTag + JavadocEmptyVersionTag + JavadocMissingExceptionDescription + JavadocMissingParamDescription + JavadocMissingThrowsDescription + // SpaceAfterCommentDelimiter -- No such rule? + // SpaceBeforeCommentDelimiter -- No such rule? + + // rulesets/concurrency.xml + BusyWait + DoubleCheckedLocking + InconsistentPropertyLocking + InconsistentPropertySynchronization + NestedSynchronization + // NoScriptBindings -- No such rule? + StaticCalendarField + StaticConnection + StaticDateFormatField + StaticMatcherField + StaticSimpleDateFormatField + SynchronizedMethod + SynchronizedOnBoxedPrimitive + SynchronizedOnGetClass + SynchronizedOnReentrantLock + SynchronizedOnString + SynchronizedOnThis + SynchronizedReadObjectMethod + SystemRunFinalizersOnExit + ThisReferenceEscapesConstructor + ThreadGroup + ThreadLocalNotStaticFinal + ThreadYield + UseOfNotifyMethod + VolatileArrayField + VolatileLongOrDoubleField + WaitOutsideOfWhileLoop + + // rulesets/convention.xml + CompileStatic + ConfusingTernary + CouldBeElvis + CouldBeSwitchStatement + FieldTypeRequired + HashtableIsObsolete + IfStatementCouldBeTernary + //ImplicitClosureParameter - use of 'it' can be cleaner than inventing a new parameter name + //ImplicitReturnStatement - we might do this occasionally + InvertedCondition + InvertedIfElse + LongLiteralWithLowerCaseL + MethodParameterTypeRequired + MethodReturnTypeRequired + NoDef + NoDouble + NoFloat + NoJavaUtilDate + NoTabCharacter + ParameterReassignment + PublicMethodsBeforeNonPublicMethods + StaticFieldsBeforeInstanceFields + //StaticMethodsBeforeInstanceMethods - DSL methods may appear in a block after the otherwise useful methods + TernaryCouldBeElvis + TrailingComma + VariableTypeRequired + VectorIsObsolete + + // rulesets/design.xml + AbstractClassWithPublicConstructor + // AbstractClassWithoutAbstractMethod - TODO: commented out because I think abstract is more explicit than a protected constructor + AssignmentToStaticFieldFromInstanceMethod + BooleanMethodReturnsNull + BuilderMethodWithSideEffects + CloneableWithoutClone + CloseWithoutCloseable + CompareToWithoutComparable + ConstantsOnlyInterface + EmptyMethodInAbstractClass + FinalClassWithProtectedMember + ImplementationAsType + Instanceof + LocaleSetDefault + NestedForLoop + OptionalCollectionReturnType + OptionalField + OptionalMethodParameter + PrivateFieldCouldBeFinal + PublicInstanceField + ReturnsNullInsteadOfEmptyArray + ReturnsNullInsteadOfEmptyCollection + SimpleDateFormatMissingLocale + StatelessSingleton + ToStringReturnsNull + + // rulesets/dry.xml + DuplicateListLiteral + DuplicateMapLiteral + DuplicateNumberLiteral + DuplicateStringLiteral + + // rulesets/enhanced.xml + // CloneWithoutCloneable + // JUnitAssertEqualsConstantActualValue + // MissingOverrideAnnotation + // UnsafeImplementationAsMap + + // rulesets/exceptions.xml + CatchArrayIndexOutOfBoundsException + CatchError + CatchException + CatchIllegalMonitorStateException + CatchIndexOutOfBoundsException + CatchNullPointerException + CatchRuntimeException + CatchThrowable + ConfusingClassNamedException + ExceptionExtendsError + ExceptionExtendsThrowable + ExceptionNotThrown + MissingNewInThrowStatement + ReturnNullFromCatchBlock + SwallowThreadDeath + ThrowError + ThrowException + ThrowNullPointerException + ThrowRuntimeException + ThrowThrowable + + // rulesets/formatting.xml + BlankLineBeforePackage + BlockEndsWithBlankLine + BlockStartsWithBlankLine + BracesForClass + BracesForForLoop + BracesForIfElse + BracesForMethod + BracesForTryCatchFinally + //ClassEndsWithBlankLine + //ClassStartsWithBlankLine + ClosureStatementOnOpeningLineOfMultipleLineClosure + ConsecutiveBlankLines + //FileEndsWithoutNewline + Indentation + LineLength + MissingBlankLineAfterImports + MissingBlankLineAfterPackage + MissingBlankLineBeforeAnnotatedField + SpaceAfterCatch + SpaceAfterClosingBrace + SpaceAfterComma + SpaceAfterFor + SpaceAfterIf + SpaceAfterMethodCallName + SpaceAfterMethodDeclarationName + SpaceAfterNotOperator + SpaceAfterOpeningBrace + SpaceAfterSemicolon + SpaceAfterSwitch + SpaceAfterWhile + SpaceAroundClosureArrow + // SpaceAroundMapEntryColon - Not sure I agree with this one + SpaceAroundOperator + SpaceBeforeClosingBrace + SpaceBeforeOpeningBrace + SpaceInsideParentheses + TrailingWhitespace + + // rulesets/generic.xml + IllegalClassMember + IllegalClassReference + IllegalPackageReference + IllegalRegex + IllegalString + IllegalSubclass + RequiredRegex + RequiredString + StatelessClass + + // rulesets/grails.xml + GrailsDomainGormMethods + GrailsDomainHasEquals + GrailsDomainHasToString + GrailsDomainReservedSqlKeywordName + GrailsDomainStringPropertyMaxSize + GrailsDomainWithServiceReference + GrailsDuplicateConstraint + GrailsDuplicateMapping + GrailsMassAssignment + GrailsPublicControllerMethod + GrailsServletContextReference + GrailsStatelessService + + // rulesets/groovyism.xml + AssignCollectionSort + AssignCollectionUnique + ClosureAsLastMethodParameter + CollectAllIsDeprecated + ConfusingMultipleReturns + ExplicitArrayListInstantiation + ExplicitCallToAndMethod + ExplicitCallToCompareToMethod + ExplicitCallToDivMethod + ExplicitCallToEqualsMethod + ExplicitCallToGetAtMethod + ExplicitCallToLeftShiftMethod + ExplicitCallToMinusMethod + ExplicitCallToModMethod + ExplicitCallToMultiplyMethod + ExplicitCallToOrMethod + ExplicitCallToPlusMethod + ExplicitCallToPowerMethod + ExplicitCallToPutAtMethod + ExplicitCallToRightShiftMethod + ExplicitCallToXorMethod + ExplicitHashMapInstantiation + ExplicitHashSetInstantiation + ExplicitLinkedHashMapInstantiation + ExplicitLinkedListInstantiation + ExplicitStackInstantiation + ExplicitTreeSetInstantiation + GStringAsMapKey + GStringExpressionWithinString + GetterMethodCouldBeProperty + GroovyLangImmutable + UseCollectMany + UseCollectNested + + // rulesets/imports.xml + DuplicateImport + ImportFromSamePackage + ImportFromSunPackages + MisorderedStaticImports + NoWildcardImports + UnnecessaryGroovyImport + UnusedImport + + // rulesets/jdbc.xml + DirectConnectionManagement + JdbcConnectionReference + JdbcResultSetReference + JdbcStatementReference + + // rulesets/junit.xml + ChainedTest + CoupledTestCase + JUnitAssertAlwaysFails + JUnitAssertAlwaysSucceeds + JUnitFailWithoutMessage + JUnitLostTest + JUnitPublicField + JUnitPublicNonTestMethod + JUnitPublicProperty + JUnitSetUpCallsSuper + JUnitStyleAssertions + JUnitTearDownCallsSuper + JUnitTestMethodWithoutAssert + JUnitUnnecessarySetUp + JUnitUnnecessaryTearDown + JUnitUnnecessaryThrowsException + SpockIgnoreRestUsed + // SpockMissingAssert -- No such rule? + UnnecessaryFail + UseAssertEqualsInsteadOfAssertTrue + UseAssertFalseInsteadOfNegation + UseAssertNullInsteadOfAssertEquals + UseAssertSameInsteadOfAssertTrue + UseAssertTrueInsteadOfAssertEquals + UseAssertTrueInsteadOfNegation + + // rulesets/logging.xml + LoggerForDifferentClass + LoggerWithWrongModifiers + LoggingSwallowsStacktrace + MultipleLoggers + PrintStackTrace + Println + SystemErrPrint + SystemOutPrint + + // rulesets/naming.xml + AbstractClassName + ClassName + ClassNameSameAsFilename + ClassNameSameAsSuperclass + // ConfusingMethodName - DSL methods are deliberately named the same as properties + // FactoryMethodName - We use "createdBy" as a property name all over the place + FieldName + InterfaceName + InterfaceNameSameAsSuperInterface + MethodName + ObjectOverrideMisspelledMethodName + PackageName + PackageNameMatchesFilePath + ParameterName + PropertyName + VariableName + + // rulesets/security.xml + FileCreateTempFile + InsecureRandom + JavaIoPackageAccess + NonFinalPublicField + NonFinalSubclassOfSensitiveInterface + ObjectFinalize + PublicFinalizeMethod + SystemExit + UnsafeArrayDeclaration + + // rulesets/serialization.xml + EnumCustomSerializationIgnored + SerialPersistentFields + SerialVersionUID + SerializableClassMustDefineSerialVersionUID + + // rulesets/size.xml + // AbcMetric // Requires the GMetrics jar - TODO: commented out for now because it's not currently helpful. + ClassSize + CrapMetric // Requires the GMetrics jar and a Cobertura coverage file + CyclomaticComplexity // Requires the GMetrics jar + MethodCount + MethodSize + NestedBlockDepth + ParameterCount + + // rulesets/unnecessary.xml + AddEmptyString + ConsecutiveLiteralAppends + ConsecutiveStringConcatenation + UnnecessaryBigDecimalInstantiation + UnnecessaryBigIntegerInstantiation + UnnecessaryBooleanExpression + UnnecessaryBooleanInstantiation + UnnecessaryCallForLastElement + UnnecessaryCallToSubstring + UnnecessaryCast + UnnecessaryCatchBlock + // UnnecessaryCollectCall - Not sure * is always easier to read. + UnnecessaryCollectionCall + UnnecessaryConstructor + UnnecessaryDefInFieldDeclaration + UnnecessaryDefInMethodDeclaration + UnnecessaryDefInVariableDeclaration + UnnecessaryDotClass + UnnecessaryDoubleInstantiation + UnnecessaryElseStatement + UnnecessaryFinalOnPrivateMethod + UnnecessaryFloatInstantiation + UnnecessaryGString + UnnecessaryGetter + UnnecessaryIfStatement + UnnecessaryInstanceOfCheck + UnnecessaryInstantiationToGetClass + UnnecessaryIntegerInstantiation + UnnecessaryLongInstantiation + UnnecessaryModOne + UnnecessaryNullCheck + UnnecessaryNullCheckBeforeInstanceOf + UnnecessaryObjectReferences + UnnecessaryOverridingMethod + UnnecessaryPackageReference + UnnecessaryParenthesesForMethodCallWithClosure + UnnecessaryPublicModifier + // UnnecessaryReturnKeyword - We might do this occasionally + UnnecessarySafeNavigationOperator + UnnecessarySelfAssignment + UnnecessarySemicolon + UnnecessarySetter + UnnecessaryStringInstantiation + UnnecessaryTernaryExpression + UnnecessaryToString + UnnecessaryTransientModifier + + // rulesets/unused.xml + UnusedArray + UnusedMethodParameter + UnusedObject + UnusedPrivateField + UnusedPrivateMethod + UnusedPrivateMethodParameter + UnusedVariable + +} \ No newline at end of file