feat!: run linters against the workspace (#5041)

- Run jscpd, gitleaks, textlint  against the entire workspace instead of
  running them over single files, one by one.
- Implement a warning function for deprecated variables.
- Deprecate the VALIDATE_JSCPD_ALL_CODEBASE variable.
- Remove duplicate configuration files when they are the same as the
  ones we provide in TEMPLATES.
- Add a missing tests for ansible-lint.
- Move ANSIBLE_DIRECTORY configuration when running tests in
  buildFileList, where similar configs are.
- Simplify ansible-lint test cases to include only what's necessary, and
  not an entire set of roles, playbooks, and inventory.
- Write instructions about major upgrades in the upgrade guide.
This commit is contained in:
Marco Ferrari 2023-12-24 17:56:15 +01:00 committed by GitHub
parent 59154bf97f
commit 11b70102c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
82 changed files with 221 additions and 2838 deletions

View file

@ -1,135 +0,0 @@
{
"arrow_spacing": {
"level": "ignore"
},
"braces_spacing": {
"level": "ignore",
"spaces": 0,
"empty_object_spaces": 0
},
"camel_case_classes": {
"level": "error"
},
"coffeescript_error": {
"level": "error"
},
"colon_assignment_spacing": {
"level": "ignore",
"spacing": {
"left": 0,
"right": 0
}
},
"cyclomatic_complexity": {
"level": "ignore",
"value": 10
},
"duplicate_key": {
"level": "error"
},
"empty_constructor_needs_parens": {
"level": "ignore"
},
"ensure_comprehensions": {
"level": "warn"
},
"eol_last": {
"level": "ignore"
},
"indentation": {
"value": 2,
"level": "warn"
},
"line_endings": {
"level": "ignore",
"value": "unix"
},
"max_line_length": {
"value": 80,
"level": "ignore",
"limitComments": true
},
"missing_fat_arrows": {
"level": "ignore",
"is_strict": false
},
"newlines_after_classes": {
"value": 3,
"level": "ignore"
},
"no_backticks": {
"level": "error"
},
"no_debugger": {
"level": "warn",
"console": false
},
"no_empty_functions": {
"level": "ignore"
},
"no_empty_param_list": {
"level": "ignore"
},
"no_implicit_braces": {
"level": "ignore",
"strict": true
},
"no_implicit_parens": {
"level": "ignore",
"strict": true
},
"no_interpolation_in_single_quotes": {
"level": "ignore"
},
"no_nested_string_interpolation": {
"level": "warn"
},
"no_plusplus": {
"level": "ignore"
},
"no_private_function_fat_arrows": {
"level": "warn"
},
"no_stand_alone_at": {
"level": "ignore"
},
"no_tabs": {
"level": "error"
},
"no_this": {
"level": "ignore"
},
"no_throwing_strings": {
"level": "error"
},
"no_trailing_semicolons": {
"level": "error"
},
"no_trailing_whitespace": {
"level": "ignore",
"allowed_in_comments": false,
"allowed_in_empty_lines": true
},
"no_unnecessary_double_quotes": {
"level": "ignore"
},
"no_unnecessary_fat_arrows": {
"level": "warn"
},
"non_empty_constructor_needs_parens": {
"level": "ignore"
},
"prefer_english_operator": {
"level": "ignore",
"doubleNotLevel": "ignore"
},
"space_operators": {
"level": "ignore"
},
"spacing_after_comma": {
"level": "ignore"
},
"transform_messes_up_line_numbers": {
"level": "warn"
}
}

View file

@ -1,68 +0,0 @@
{
"extends": "recommended",
"rules": {
"CatchException": {
"enabled": false
},
"CatchThrowable": {
"enabled": false
},
"ClassJavadoc": {
"enabled": false
},
"ClassNameSameAsFilename": {
"enabled": false
},
"ClosureAsLastMethodParameter": {
"enabled": false
},
"DuplicateNumberLiteral": {
"enabled": false
},
"DuplicateStringLiteral": {
"enabled": false
},
"FieldTypeRequired": {
"enabled": false
},
"JavaIoPackageAccess": {
"enabled": false
},
"MethodParameterTypeRequired": {
"enabled": false
},
"MethodSize": {
"enabled": false
},
"NoDef": {
"enabled": false
},
"PrintStackTrace": {
"enabled": false
},
"PropertyName": {
"enabled": false
},
"SpaceAroundMapEntryColon": {
"enabled": false
},
"SystemExit": {
"enabled": false
},
"UnnecessaryGetter": {
"enabled": false
},
"UnnecessaryObjectReferences": {
"enabled": false
},
"UnnecessarySetter": {
"enabled": false
},
"VariableName": {
"enabled": false
},
"VariableTypeRequired": {
"enabled": false
}
}
}

View file

@ -0,0 +1,10 @@
{
"absolute": true,
"ignore": [
"**/node_modules/**"
],
"reporters": [
"consoleFull"
],
"threshold": 0
}

View file

@ -1,6 +1,39 @@
{
"absolute": true,
"ignore": [
"**/ISSUE_TEMPLATE/bug_report.yml",
"**/ISSUE_TEMPLATE/feature_request.yml",
"**/node_modules/**",
"**/test/linters/ansible/**",
"**/test/linters/clojure",
"**/test/linters/cloudformation",
"**/test/linters/coffeescript",
"**/test/linters/css",
"**/test/linters/html",
"**/test/linters/javascript_es",
"**/test/linters/javascript_prettier",
"**/test/linters/javascript_standard",
"**/test/linters/jscpd/bad",
"**/test/linters/latex",
"**/test/linters/perl",
"**/test/linters/php_builtin",
"**/test/linters/php_phpcs",
"**/test/linters/php_phpstan",
"**/test/linters/php_psalm",
"**/test/linters/protobuf",
"**/test/linters/python_black",
"**/test/linters/python_flake8",
"**/test/linters/python_isort",
"**/test/linters/python_mypy",
"**/test/linters/python_pylint",
"**/test/linters/r",
"**/test/linters/ruby",
"**/test/linters/rust_2015",
"**/test/linters/rust_2018",
"**/test/linters/rust_2021",
"**/test/linters/scalafmt",
"**/test/linters/tekton/**",
"**/test/linters/typescript_es/**",
"**/workflows/cd.yml"
],
"reporters": [

View file

View file

@ -1,59 +0,0 @@
---
###########################################
# These are the rules used for #
# linting all the yaml files in the stack #
# NOTE: #
# You can disable line with: #
# # yamllint disable-line #
###########################################
rules:
braces:
level: warning
min-spaces-inside: 0
max-spaces-inside: 0
min-spaces-inside-empty: 1
max-spaces-inside-empty: 5
brackets:
level: warning
min-spaces-inside: 0
max-spaces-inside: 0
min-spaces-inside-empty: 1
max-spaces-inside-empty: 5
colons:
level: warning
max-spaces-before: 0
max-spaces-after: 1
commas:
level: warning
max-spaces-before: 0
min-spaces-after: 1
max-spaces-after: 1
comments: disable
comments-indentation: disable
document-end: disable
document-start:
level: warning
present: true
empty-lines:
level: warning
max: 2
max-start: 0
max-end: 0
hyphens:
level: warning
max-spaces-after: 1
indentation:
level: warning
spaces: consistent
indent-sequences: true
check-multi-line-strings: false
key-duplicates: enable
line-length:
level: warning
max: 1024
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
new-line-at-end-of-file: disable
new-lines:
type: unix
trailing-spaces: disable

View file

@ -1,57 +0,0 @@
---
##########################
##########################
## Dart Linter rules ##
##########################
##########################
# Pedantic Rules
# https://github.com/dart-lang/pedantic
linter:
rules:
- always_declare_return_types
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_empty_else
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_relative_lib_imports
- avoid_return_types_on_setters
- avoid_shadowing_type_parameters
- avoid_types_as_parameter_names
- camel_case_extensions
- curly_braces_in_flow_control_structures
- empty_catches
- empty_constructor_bodies
- library_names
- library_prefixes
- no_duplicate_case_values
- null_closures
- omit_local_variable_types
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_contains
- prefer_equal_for_default_values
- prefer_final_fields
- prefer_for_elements_to_map_fromIterable
- prefer_generic_function_type_aliases
- prefer_if_null_operators
- prefer_is_empty
- prefer_is_not_empty
- prefer_iterable_whereType
- prefer_single_quotes
- prefer_spread_collections
- recursive_getters
- slash_for_doc_comments
- type_init_formals
- unawaited_futures
- unnecessary_const
- unnecessary_new
- unnecessary_null_in_if_null_operators
- unnecessary_this
- unrelated_type_equality_checks
- use_function_type_syntax_for_parameters
- use_rethrow_when_possible
- valid_regexps

View file

@ -1,201 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the sun coding conventions from:
- the Java Language Specification at
https://docs.oracle.com/javase/specs/jls/se11/html/index.html
- the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
- the Javadoc guidelines at
https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html
- the JDK Api documentation https://docs.oracle.com/en/java/javase/11/
- some best practices
Checkstyle is very configurable. Be sure to read the documentation at
https://checkstyle.org (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
To suppress certain violations please review suppression filters.
Finally, it is worth reading the documentation.
-->
<module name="Checker">
<!--
If you set the basedir property below, then all reported file
names will be relative to the specified directory. See
https://checkstyle.org/config.html#Checker
<property name="basedir" value="${basedir}"/>
-->
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
<property name="file" value="${org.checkstyle.sun.suppressionfilter.config}" default="checkstyle-suppressions.xml" />
<property name="optional" value="true"/>
</module>
<!-- Checks that a package-info.java file exists for each package. -->
<!-- See https://checkstyle.org/config_javadoc.html#JavadocPackage -->
<!-- <module name="JavadocPackage"/> -->
<!-- Checks whether files end with a new line. -->
<!-- See https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- Checks that property files contain the same keys. -->
<!-- See https://checkstyle.org/config_misc.html#Translation -->
<module name="Translation"/>
<!-- Checks for Size Violations. -->
<!-- See https://checkstyle.org/config_sizes.html -->
<module name="FileLength"/>
<module name="LineLength">
<property name="fileExtensions" value="java"/>
</module>
<!-- Checks for whitespace -->
<!-- See https://checkstyle.org/config_whitespace.html -->
<module name="FileTabCharacter"/>
<!-- Miscellaneous other checks. -->
<!-- See https://checkstyle.org/config_misc.html -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="minimum" value="0"/>
<property name="maximum" value="0"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<!-- Checks for Headers -->
<!-- See https://checkstyle.org/config_header.html -->
<!-- <module name="Header"> -->
<!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
<!-- <property name="fileExtensions" value="java"/> -->
<!-- </module> -->
<!-- Enables @SuppressWarnings Support -->
<module name="SuppressWarningsFilter"/>
<module name="TreeWalker">
<!-- Checks for Javadoc comments. -->
<!-- See https://checkstyle.org/config_javadoc.html -->
<module name="InvalidJavadocPosition"/>
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocVariable"/>
<module name="JavadocStyle"/>
<module name="MissingJavadocMethod"/>
<!-- Enables @SuppressWarnings Support -->
<module name="SuppressWarningsHolder"/>
<!-- Checks for Naming Conventions. -->
<!-- See https://checkstyle.org/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See https://checkstyle.org/config_imports.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports">
<property name="processJavadoc" value="false"/>
</module>
<!-- Checks for Size Violations. -->
<!-- See https://checkstyle.org/config_sizes.html -->
<module name="MethodLength"/>
<module name="ParameterNumber"/>
<!-- Checks for whitespace -->
<!-- See https://checkstyle.org/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See https://checkstyle.org/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See https://checkstyle.org/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See https://checkstyle.org/config_coding.html -->
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField"/>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="MultipleVariableDeclarations"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See https://checkstyle.org/config_design.html -->
<module name="DesignForExtension"/>
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier"/>
<!-- Miscellaneous other checks. -->
<!-- See https://checkstyle.org/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
<module name="SuppressionXpathFilter">
<property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}" default="checkstyle-xpath-suppressions.xml" />
<property name="optional" value="true"/>
</module>
</module>
</module>

View file

@ -9,9 +9,9 @@ Fixes #
## Proposed Changes
1. ...
2. ...
3. ...
- ...
- ...
- ...
## Readiness Checklist
@ -23,6 +23,7 @@ In order to have this pull request merged, complete the following tasks.
- [ ] I provided the necessary tests.
- [ ] I squashed all the commits into a single commit.
- [ ] I followed the [Conventional Commit v1.0.0 spec](https://www.conventionalcommits.org/en/v1.0.0/).
- [ ] If this is a breaking change, write upgrade instructions in the [upgrade guide](../docs/upgrade-guide.md).
### Super-linter maintainer tasks

9
.gitleaksignore Normal file
View file

@ -0,0 +1,9 @@
.github-personal-access-token:github-fine-grained-pat:1
/github/workspace/.github-personal-access-token:github-fine-grained-pat:1
/github/workspace/test/linters/gitleaks/bad/gitleaks_bad_01.txt:aws-access-token:1
/github/workspace/test/linters/gitleaks/bad/gitleaks_bad_01.txt:generic-api-key:2
/tmp/lint/.github-personal-access-token:github-fine-grained-pat:1
/tmp/lint/test/linters/gitleaks/bad/gitleaks_bad_01.txt:aws-access-token:1
/tmp/lint/test/linters/gitleaks/bad/gitleaks_bad_01.txt:generic-api-key:2
test/linters/gitleaks/bad/gitleaks_bad_01.txt:aws-access-token:1
test/linters/gitleaks/bad/gitleaks_bad_01.txt:generic-api-key:2

5
.textlintignore Normal file
View file

@ -0,0 +1,5 @@
test/linters/jscpd/good/markdown_good_1.md
test/linters/markdown/markdown_bad_1.md
test/linters/markdown/markdown_bad_1.md
test/linters/markdown/markdown_good_1.md
test/linters/natural_language/bad/natural_language_bad_01.md

View file

@ -149,6 +149,7 @@ lint-codebase: ## Lint the entire codebase
-e ENABLE_GITHUB_ACTIONS_GROUP_TITLE=true \
-e ERROR_ON_MISSING_EXEC_BIT=true \
-e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" \
-e VALIDATE_ALL_CODEBASE=true \
-v "$(CURDIR):/tmp/lint" \
$(SUPER_LINTER_TEST_CONTAINER_URL)
@ -167,11 +168,11 @@ test-build-file-list: ## Test buildFileList
test-linters: ## Run the linters test suite
docker run \
-e ACTIONS_RUNNER_DEBUG=true \
-e ANSIBLE_DIRECTORY=test/linters/ansible \
-e CHECKOV_FILE_NAME=".checkov-test-linters.yaml" \
-e DEFAULT_BRANCH=main \
-e ENABLE_GITHUB_ACTIONS_GROUP_TITLE=true \
-e ERROR_ON_MISSING_EXEC_BIT=true \
-e JSCPD_CONFIG_FILE=".jscpd-test-linters.json" \
-e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" \
-e RUN_LOCAL=true \
-e TEST_CASE_RUN=true \

View file

@ -119,6 +119,11 @@ To run super-linter as a GitHub Action, you do the following:
1. Push the new commit to the remote repository.
1. Create a new pull request to observe the results.
## Upgrade to newer super-linter versions
For more information about upgrading super-linter to a new major version, see
the [upgrade guide](docs/upgrade-guide.md).
## Add Super-Linter badge in your repository README
You can show Super-Linter status with a badge in your repository README:
@ -165,7 +170,6 @@ You can configure super-linter using the following environment variables:
| **EDITORCONFIG_FILE_NAME** | `.ecrc` | Filename for [editorconfig-checker configuration](https://github.com/editorconfig-checker/editorconfig-checker) |
| **ENABLE_GITHUB_ACTIONS_GROUP_TITLE** | `false` if `RUN_LOCAL=true`, `true` otherwise | Flag to enable [GitHub Actions log grouping](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines). |
| **ERROR_ON_MISSING_EXEC_BIT** | `false` | If set to `false`, the `bash-exec` linter will report a warning if a shell script is not executable. If set to `true`, the `bash-exec` linter will report an error instead. |
| **EXPERIMENTAL_BATCH_WORKER** | `false` | Flag to enable experimental parallel and batched worker. As of current only `eslint` and `cfn-lint` are supported, if there is no support, original version is used as fallback |
| **FILTER_REGEX_EXCLUDE** | `none` | Regular expression defining which files will be excluded from linting (ex: `.*src/test.*`) |
| **FILTER_REGEX_INCLUDE** | `all` | Regular expression defining which files will be processed by linters (ex: `.*src/.*`) |
| **GITHUB_ACTIONS_CONFIG_FILE** | `actionlint.yml` | Filename for [Actionlint configuration](https://github.com/rhysd/actionlint/blob/main/docs/config.md) (ex: `actionlint.yml`) |
@ -215,7 +219,6 @@ You can configure super-linter using the following environment variables:
| **TYPESCRIPT_STANDARD_TSCONFIG_FILE** | `${DEFAULT_WORKSPACE}/tsconfig.json` | Path to the [TypeScript project configuration](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) in [ts-standard](https://github.com/standard/ts-standard). The path is relative to `DEFAULT_WORKSPACE` |
| **USE_FIND_ALGORITHM** | `false` | By default, we use `git diff` to find all files in the workspace and what has been updated, this would enable the Linux `find` method instead to find all files to lint |
| **VALIDATE_ALL_CODEBASE** | `true` | Will parse the entire repository and find all files to validate across all types. **NOTE:** When set to `false`, only **new** or **edited** files will be parsed for validation. |
| **VALIDATE_JSCPD_ALL_CODEBASE** | `false` | If set to `true`, will lint the whole codebase with JSCPD. If set to `false`, JSCPD will only lint files one by one. |
| **VALIDATE_ANSIBLE** | `true` | Flag to enable or disable the linting process of the Ansible language. |
| **VALIDATE_ARM** | `true` | Flag to enable or disable the linting process of the ARM language. |
| **VALIDATE_BASH** | `true` | Flag to enable or disable the linting process of the Bash language. |

View file

@ -4,7 +4,8 @@
"consoleFull"
],
"ignore": [
"**/__snapshots__/**"
"**/__snapshots__/**",
"**/node_modules/**"
],
"absolute": true
}

41
docs/upgrade-guide.md Normal file
View file

@ -0,0 +1,41 @@
# Super-linter upgrade guide
This document helps you upgrade from a super-linter version to newer ones:
- [Upgrade from v5 to v6](#upgrade-from-v5-to-v6)
## Upgrade from v5 to v6
This section helps you migrate from super-linter `v5` to `v6`.
### Experimental batch workers
- Experimental batch support is deprecated. You can safely remove the
`EXPERIMENTAL_BATCH_WORKER` variable from your configuration.
### Gitleaks
- If you defined secret patterns in `.gitleaks.toml`, Gitleaks may report errors
about that file. If this happens, you can
[configure Gitleaks to ignore that file](https://github.com/gitleaks/gitleaks/tree/master?tab=readme-ov-file#gitleaksignore).
- Gitleaks doesn't consider the `FILTER_REGEX_EXCLUDE`, `FILTER_REGEX_INCLUDE`,
`IGNORE_GENERATED_FILES`, `IGNORE_GITIGNORED_FILES` variables. For more
information about how to ignore files with Gitleaks, see
[the Gitleaks documentation](https://github.com/gitleaks/gitleaks/tree/master?tab=readme-ov-file#gitleaksignore).
### Jscpd
- The `VALIDATE_JSCPD_ALL_CODEBASE` variable is deprecated. Jscpd now lints the
entire workspace instead of linting files one by one. You can safely remove
the `VALIDATE_JSCPD_ALL_CODEBASE` variable from your configuration.
- Jscpd doesn't consider the `FILTER_REGEX_EXCLUDE`, `FILTER_REGEX_INCLUDE`,
`IGNORE_GENERATED_FILES`, `IGNORE_GITIGNORED_FILES` variables. For more
information about how to ignore files with Jscpd, see
[the Jscpd documentation](https://github.com/kucherenko/jscpd/tree/master/packages/jscpd).
### textlint
- textlint doesn't consider the `FILTER_REGEX_EXCLUDE`, `FILTER_REGEX_INCLUDE`,
`IGNORE_GENERATED_FILES`, `IGNORE_GITIGNORED_FILES` variables. For more
information about how to ignore files with textlint, see
[the textlint documentation](https://textlint.github.io/docs/ignore.html).

View file

@ -65,9 +65,6 @@ function BuildFileList() {
TEST_CASE_RUN="${2}"
debug "TEST_CASE_RUN: ${TEST_CASE_RUN}"
ANSIBLE_DIRECTORY="${3}"
debug "ANSIBLE_DIRECTORY: ${ANSIBLE_DIRECTORY}"
if [ "${VALIDATE_ALL_CODEBASE}" == "false" ] && [ "${TEST_CASE_RUN}" != "true" ]; then
debug "----------------------------------------------"
debug "Build the list of all changed files"
@ -140,14 +137,67 @@ function BuildFileList() {
warn "No files were found in the GITHUB_WORKSPACE:[${GITHUB_WORKSPACE}] to lint!"
fi
#########################################
# Check if the Ansible directory exists #
#########################################
if [ -d "${ANSIBLE_DIRECTORY}" ]; then
debug "Adding ANSIBLE_DIRECTORY (${ANSIBLE_DIRECTORY}) to the list of files and directories to lint."
FILE_ARRAY_ANSIBLE+=("${ANSIBLE_DIRECTORY}")
####################################################
# Configure linters that scan the entire workspace #
####################################################
debug "Checking if we are in test mode before configuring the list of directories to lint"
if [ "${TEST_CASE_RUN}" == "true" ]; then
debug "We are running in test mode."
debug "Adding test case directories to the list of directories to analyze with ansible-lint."
DEFAULT_ANSIBLE_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/ansible"
debug "DEFAULT_ANSIBLE_TEST_CASE_DIRECTORY: ${DEFAULT_ANSIBLE_TEST_CASE_DIRECTORY}"
FILE_ARRAY_ANSIBLE+=("${DEFAULT_ANSIBLE_TEST_CASE_DIRECTORY}/bad")
FILE_ARRAY_ANSIBLE+=("${DEFAULT_ANSIBLE_TEST_CASE_DIRECTORY}/good")
debug "Adding test case directories to the list of directories to analyze with Checkov."
DEFAULT_CHECKOV_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/checkov"
debug "DEFAULT_CHECKOV_TEST_CASE_DIRECTORY: ${DEFAULT_CHECKOV_TEST_CASE_DIRECTORY}"
FILE_ARRAY_CHECKOV+=("${DEFAULT_CHECKOV_TEST_CASE_DIRECTORY}/bad")
FILE_ARRAY_CHECKOV+=("${DEFAULT_CHECKOV_TEST_CASE_DIRECTORY}/good")
debug "Adding test case directories to the list of directories to analyze with Gitleaks."
DEFAULT_GITLEAKS_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/gitleaks"
debug "DEFAULT_GITLEAKS_TEST_CASE_DIRECTORY: ${DEFAULT_GITLEAKS_TEST_CASE_DIRECTORY}"
FILE_ARRAY_GITLEAKS+=("${DEFAULT_GITLEAKS_TEST_CASE_DIRECTORY}/bad")
FILE_ARRAY_GITLEAKS+=("${DEFAULT_GITLEAKS_TEST_CASE_DIRECTORY}/good")
debug "Adding test case directories to the list of directories to analyze with Checkov."
DEFAULT_JSCPD_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/jscpd"
debug "DEFAULT_JSCPD_TEST_CASE_DIRECTORY: ${DEFAULT_JSCPD_TEST_CASE_DIRECTORY}"
FILE_ARRAY_JSCPD+=("${DEFAULT_JSCPD_TEST_CASE_DIRECTORY}/bad")
FILE_ARRAY_JSCPD+=("${DEFAULT_JSCPD_TEST_CASE_DIRECTORY}/good")
debug "Adding test case directories to the list of directories to analyze with textlint."
DEFAULT_NATURAL_LANGUAGE_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/natural_language"
debug "DEFAULT_NATURAL_LANGUAGE_TEST_CASE_DIRECTORY: ${DEFAULT_NATURAL_LANGUAGE_TEST_CASE_DIRECTORY}"
FILE_ARRAY_NATURAL_LANGUAGE+=("${DEFAULT_NATURAL_LANGUAGE_TEST_CASE_DIRECTORY}/bad")
FILE_ARRAY_NATURAL_LANGUAGE+=("${DEFAULT_NATURAL_LANGUAGE_TEST_CASE_DIRECTORY}/good")
else
debug "ANSIBLE_DIRECTORY (${ANSIBLE_DIRECTORY}) does NOT exist."
debug "We are not running in test mode (${TEST_CASE_RUN})."
if [ -d "${ANSIBLE_DIRECTORY}" ]; then
debug "Adding ANSIBLE_DIRECTORY (${ANSIBLE_DIRECTORY}) to the list of files and directories to lint."
FILE_ARRAY_ANSIBLE+=("${ANSIBLE_DIRECTORY}")
else
debug "ANSIBLE_DIRECTORY (${ANSIBLE_DIRECTORY}) does NOT exist."
fi
if CheckovConfigurationFileContainsDirectoryOption "${CHECKOV_LINTER_RULES}"; then
debug "No need to configure the directories to check for Checkov."
else
debug "Adding ${GITHUB_WORKSPACE} to the list of directories to analyze with Checkov."
FILE_ARRAY_CHECKOV+=("${GITHUB_WORKSPACE}")
fi
debug "Adding ${GITHUB_WORKSPACE} to the list of directories to analyze with Gitleaks."
FILE_ARRAY_GITLEAKS+=("${GITHUB_WORKSPACE}")
debug "Adding ${GITHUB_WORKSPACE} to the list of directories to analyze with JSCPD."
FILE_ARRAY_JSCPD+=("${GITHUB_WORKSPACE}")
debug "Adding ${GITHUB_WORKSPACE} to the list of directories to analyze with textlint."
FILE_ARRAY_NATURAL_LANGUAGE+=("${GITHUB_WORKSPACE}")
fi
if CheckovConfigurationFileContainsDirectoryOption "${CHECKOV_LINTER_RULES}"; then
@ -239,22 +289,6 @@ function BuildFileList() {
# Editorconfig-checker should check every file
FILE_ARRAY_EDITORCONFIG+=("${FILE}")
# Textlint should check every file
FILE_ARRAY_NATURAL_LANGUAGE+=("${FILE}")
if [ "${VALIDATE_JSCPD_ALL_CODEBASE}" == "true" ]; then
debug "Not adding ${FILE} to FILE_ARRAY_JSCPD because we're going to lint the whole codebase anyway."
else
# jscpd also runs an all files
FILE_ARRAY_JSCPD+=("${FILE}")
fi
# Need to make sure we dont check the secrets paterns
# for secrets, as it will pop!
if [ "${BASE_FILE}" != ".gitleaks.toml" ]; then
# GitLeaks also runs an all files
FILE_ARRAY_GITLEAKS+=("${FILE}")
fi
# See https://docs.renovatebot.com/configuration-options/
if [[ "${BASE_FILE}" =~ renovate.json5? ]] ||
[ "${BASE_FILE}" == ".renovaterc" ] || [[ "${BASE_FILE}" =~ .renovaterc.json5? ]]; then
@ -800,11 +834,6 @@ function BuildFileList() {
debug ""
done
if [ "${VALIDATE_JSCPD_ALL_CODEBASE}" == "true" ]; then
debug "Adding the root of the workspaces to the list of files and directories to lint with JSCPD..."
FILE_ARRAY_JSCPD+=("${GITHUB_WORKSPACE}")
fi
################
# Footer print #
################

View file

@ -1,58 +0,0 @@
# Parallel / Batched Workers
Running linters in parallel, and if possible in batch to speed up the linting process.
This is an experimental feature, and is not enabled by default, but it is really fast if you enable it and have the linter support implemented.
Since it is a parallel version, it might not be possible to reproduce a line-by-line match of serial output.
In order to maximize compatibility to programs using output of super-linter, the following are guarenteed:
- Every linter error reported in serial version is reported by parallel version [^linter-error];
- Super-linter log-level WARN and above that appears in serial version should appear in this version;
- Super-linter log-level INFO and above do not interleave between linter output;
- Failed file count logged at the end of super-linter matches serial version;
[^linter-error]: Statistics are almost impossible to reproduce, e.g. was always `1 file linted, K errors` but now `M files linted, K errors`, I guess it is fine as the stat for linting 1 file produced by linter is not very useful.
## Motivation
Some linter might have a high startup cost, e.g.
- `eslint` with some popular frontend framework plugins requires reading thousands of js files to init
- `cfn-lint` which requires reading the whole cloudformation spec to run
A lot of linter supports linting multiple files per invocation, i.e. `<linter-name> file1 file2 file3 ...`, which can be leveraged to reduce the startup overhead.
Modern CI/CD might be on a multi-core machine, so running multiple linters in parallel can also speed up linting process, shorten the time taken from push to deploy.
Shift-left paradigm encourages running linters in the IDE, for example in `.githooks/pre-commit`, linting need to be fast for good Developer experience.
## Supported linters
| Linter | Batch | Parallel | Notes |
| -------- | ----- | -------- | --------------------------- |
| cfn-lint | o | o | |
| ESLint | o | o | |
| gitleaks | | o | Batch unsupported by linter |
## Architecture
By setting `EXPERIMENTAL_BATCH_WORKER=true`, the following code path will be enabled:
```bash
# ../worker.sh
LintCodebase
# ./${LinterName}.sh
# TASK: Modify linter command for batch, parallelization and batching parameters suitable for the linter
ParallelLintCodebase${LinterName}
# ./base.sh
# gnu parallel run
ParallelLintCodebaseImpl
# ./${LinterName}.sh
# TASK: see ./base.sh
LintCodebase${LinterName}StdoutParser
# ./${LinterName}.sh
# TASK: see ./base.sh
LintCodebase${LinterName}StderrParser
# ./base.sh if the default works for you
LintCodebaseBaseStderrParser
```

View file

@ -1,116 +0,0 @@
#!/usr/bin/env bash
# stderr contains `parallel` command trace (starting with $LINTER_COMMAND) and linter's stderr
#
# implement to report error count and traces correctly
#
# IN: pipe from ${STDERR_PIPENAME}
# - multiline text input
# OUT: pipe to ${STDERR_PIPENAME}.return number of file with linter error
# - int: number of file with linter error
function LintCodebaseBaseStderrParser() {
local STDERR_PIPENAME="${1}" && shift
local LINTER_NAME="${1}" && shift
local LINTER_COMMAND="${1}" && shift
# usually linter reports failing linter rules to stdout
# stderr contains uncaught linter errors e.g. invalid parameter, which shall indicate a bug in the parallel implementation
# as the origin of error is unknown, we shall count each instance of linter error as 1 file to alert user of an error
local UNCAUGHT_LINTER_ERRORS=0
local LINE
while IFS= read -r LINE; do
if [[ "${LINE}" == "${LINTER_COMMAND}"* ]]; then
trace "[parallel] ${LINE}"
continue
fi
error "[${LINTER_NAME}] ${LINE//\\/\\\\}"
UNCAUGHT_LINTER_ERRORS="$((UNCAUGHT_LINTER_ERRORS + 1))"
done <"${STDERR_PIPENAME}"
echo "${UNCAUGHT_LINTER_ERRORS}" >"${STDERR_PIPENAME}.return"
return 0
}
# stdout is piped from linter's stdout
# * this stream is already `tee`-ed to stdout by caller as in serial super-linter behavior
#
# implement to report error count correctly
#
# IN: pipe from ${STDERR_PIPENAME}
# - multiline text input
# OUT: pipe to ${STDERR_PIPENAME}.return
# - int: number of file with linter error
function LintCodebaseBaseStdoutParser() {
local STDOUT_PIPENAME="${1}" && shift
local LINTER_NAME="${1}" && shift
# this function is an example only to illustrate the interface
# should be implemented for each linter, do not use this
# * you can use any way to parse the linter output as you like
fatal "LintCodebaseBaseStdoutParser is not implemented"
echo 0 >"${STDOUT_PIPENAME}.return"
return 0
}
# This function runs linter in parallel and batch#
# To reproduce serial behavior, ERRORS_FOUND_${FILE_TYPE} should be calculated from linter output
# The calculation should not affect, break or interleave linter output in any way
# logging level below info is allowed to interleave linter output
function ParallelLintCodebaseImpl() {
local FILE_TYPE="${1}" && shift # File type (Example: JSON)
local LINTER_NAME="${1}" && shift # Linter name (Example: jsonlint)
local LINTER_COMMAND="${1}" && shift # Full linter command including linter name (Example: jsonlint -c ConfigFile /path/to/file)
# shellcheck disable=SC2034
local TEST_CASE_RUN="${1}" && shift # Flag for if running in test cases
local NUM_PROC="${1}" && shift # Number of processes to run in parallel
local FILES_PER_PROC="${1}" && shift # Max. number of file to pass into one linter process, still subject to maximum of 65536 characters per command line, which parallel will handle for us
local STDOUT_PARSER="${1}" && shift # Function to parse stdout to count number of files with linter error
local STDERR_PARSER="${1}" && shift # Function to parse stderr to count number of files with linter error
local FILE_ARRAY=("$@") # Array of files to validate (Example: ${FILE_ARRAY_JSON})
debug "Running ParallelLintCodebaseImpl on ${#FILE_ARRAY[@]} files. FILE_TYPE: ${FILE_TYPE}, LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}, TEST_CASE_RUN: ${TEST_CASE_RUN}, NUM_PROC: ${NUM_PROC}, FILES_PER_PROC: ${FILES_PER_PROC}, STDOUT_PARSER: ${STDOUT_PARSER}, STDERR_PARSER: ${STDERR_PARSER}"
local PARALLEL_DEBUG_OPTS=""
if [ "${LOG_TRACE}" == "true" ]; then
PARALLEL_DEBUG_OPTS="--verbose"
fi
local PARALLEL_COMMAND="parallel --will-cite --keep-order --max-lines ${FILES_PER_PROC} --max-procs ${NUM_PROC} ${PARALLEL_DEBUG_OPTS} --xargs ${LINTER_COMMAND}"
info "Parallel command: ${PARALLEL_COMMAND}"
# named pipes for routing linter outputs and return values
local STDOUT_PIPENAME="/tmp/parallel-${FILE_TYPE,,}.stdout"
local STDERR_PIPENAME="/tmp/parallel-${FILE_TYPE,,}.stderr"
trace "Stdout pipe: ${STDOUT_PIPENAME}"
trace "Stderr pipe: ${STDERR_PIPENAME}"
mkfifo "${STDOUT_PIPENAME}" "${STDOUT_PIPENAME}.return" "${STDERR_PIPENAME}" "${STDERR_PIPENAME}.return"
# start all functions in bg
"${STDOUT_PARSER}" "${STDOUT_PIPENAME}" "${LINTER_NAME}" &
"${STDERR_PARSER}" "${STDERR_PIPENAME}" "${LINTER_NAME}" "${LINTER_COMMAND}" &
# start linter in parallel
printf "%s\n" "${FILE_ARRAY[@]}" | ${PARALLEL_COMMAND} 2>"${STDERR_PIPENAME}" | tee "${STDOUT_PIPENAME}" &
local UNCAUGHT_LINTER_ERRORS
local ERRORS_FOUND
# wait for all parsers to finish, should read a number from each pipe
IFS= read -r UNCAUGHT_LINTER_ERRORS <"${STDERR_PIPENAME}.return"
trace "UNCAUGHT_LINTER_ERRORS: ${UNCAUGHT_LINTER_ERRORS}"
IFS= read -r ERRORS_FOUND <"${STDOUT_PIPENAME}.return"
trace "ERRORS_FOUND: ${ERRORS_FOUND}"
# assert return values are integers >= 0 just in case some implementation error
if ! [[ "${ERRORS_FOUND}" =~ ^[0-9]+$ ]]; then
fatal "ERRORS_FOUND is not a number: ${ERRORS_FOUND}"
exit 1
fi
if ! [[ "${UNCAUGHT_LINTER_ERRORS}" =~ ^[0-9]+$ ]]; then
fatal "UNCAUGHT_LINTER_ERRORS is not a number: ${UNCAUGHT_LINTER_ERRORS}"
exit 1
fi
ERRORS_FOUND=$((ERRORS_FOUND + UNCAUGHT_LINTER_ERRORS))
printf -v "ERRORS_FOUND_${FILE_TYPE}" "%d" "${ERRORS_FOUND}"
return 0
}

View file

@ -1,57 +0,0 @@
#!/usr/bin/env bash
# Sample cfn-lint v0.x output:
#
# E3002 Invalid Property Resources/Whatever/Properties/Is/Wrong
# ./path/to/my-stack.yml:35:7
#
function LintCodebaseCfnLintStdoutParser() {
local STDOUT_PIPENAME="${1}" && shift
local LINTER_NAME="${1}" && shift
local ERRORS_FOUND=0
local IS_ERROR
local CUR_FILENAME
local NEXT_FILENAME
local LINE
while IFS= read -r LINE; do
if grep "[EW][0-9]\+[[:space:]]" <<<"$LINE" >/dev/null; then
IS_ERROR="true"
continue
fi
if grep "$PWD" <<<"$LINE" >/dev/null; then
NEXT_FILENAME=$(cut -d: -f1 <<<"$LINE")
if [[ "$NEXT_FILENAME" != "$CUR_FILENAME" ]]; then
CUR_FILENAME=$NEXT_FILENAME
if [[ "$IS_ERROR" == "true" ]]; then
IS_ERROR="false"
ERRORS_FOUND=$((ERRORS_FOUND + 1))
fi
fi
continue
fi
done <"${STDOUT_PIPENAME}"
echo "${ERRORS_FOUND}" >"${STDOUT_PIPENAME}.return"
return 0
}
function ParallelLintCodebaseCfnLint() {
local FILE_TYPE="${1}" && shift
local LINTER_NAME="${1}" && shift
local LINTER_COMMAND="${1}" && shift
local TEST_CASE_RUN="${1}" && shift
local FILE_ARRAY=("$@")
local NUM_PROC="$(($(nproc) * 1))"
local FILES_PER_PROC="16"
local STDOUT_PARSER="LintCodebaseCfnLintStdoutParser"
local STDERR_PARSER="LintCodebaseBaseStderrParser"
info "Running EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}, TEST_CASE_RUN: ${TEST_CASE_RUN}"
ParallelLintCodebaseImpl "${FILE_TYPE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${TEST_CASE_RUN}" "${NUM_PROC}" "${FILES_PER_PROC}" "${STDOUT_PARSER}" "${STDERR_PARSER}" "${FILE_ARRAY[@]}"
info "Exiting EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. ERROR_FOUND: ${ERRORS_FOUND}. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}"
return 0
}

View file

@ -1,51 +0,0 @@
#!/usr/bin/env bash
# Sample eslint output:
#
# /path/to/failed.js
# 11:5 error 'a' is never reassigned. Use 'const' instead prefer-const
# 11:5 error 'a' is assigned a value but never used no-unused-vars
#
function LintCodebaseEslintStdoutParser() {
local STDOUT_PIPENAME="${1}" && shift
local LINTER_NAME="${1}" && shift
local ERRORS_FOUND=0
local CUR_FILE_COUNTED
local LINE
while IFS= read -r LINE; do
if grep "$PWD" <<<"$LINE" >/dev/null; then
CUR_FILE_COUNTED="false"
continue
fi
if grep "[[:space:]]\+[0-9]\+:[0-9]\+[[:space:]]\+error[[:space:]]\+" <<<"$LINE" >/dev/null; then
if [[ "$CUR_FILE_COUNTED" == "false" ]]; then
CUR_FILE_COUNTED="true"
ERRORS_FOUND=$((ERRORS_FOUND + 1))
fi
fi
done <"${STDOUT_PIPENAME}"
echo "${ERRORS_FOUND}" >"${STDOUT_PIPENAME}.return"
return 0
}
function ParallelLintCodebaseEslint() {
local FILE_TYPE="${1}" && shift
local LINTER_NAME="${1}" && shift
local LINTER_COMMAND="${1}" && shift
local TEST_CASE_RUN="${1}" && shift
local FILE_ARRAY=("$@")
local NUM_PROC="$(($(nproc) * 1))"
local FILES_PER_PROC="64"
local STDOUT_PARSER="LintCodebaseEslintStdoutParser"
local STDERR_PARSER="LintCodebaseBaseStderrParser"
info "Running EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}, TEST_CASE_RUN: ${TEST_CASE_RUN}"
ParallelLintCodebaseImpl "${FILE_TYPE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${TEST_CASE_RUN}" "${NUM_PROC}" "${FILES_PER_PROC}" "${STDOUT_PARSER}" "${STDERR_PARSER}" "${FILE_ARRAY[@]}"
info "Exiting EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. ERROR_FOUND: ${ERRORS_FOUND}. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}"
return 0
}

View file

@ -1,60 +0,0 @@
#!/usr/bin/env bash
# gitleaks reports failing linter rules to stdout
# stderr contains uncaught linter errors e.g. invalid parameter, which shall indicate a bug in this script
# using default LintCodebaseBaseStderrParser
# Sample gitleaks output:
#
# Finding: API_KEY=XXXXXXXXX
# Secret: XXXXXXXXX
# RuleID: generic-api-key
# Entropy: 1.000000
# File: /tmp/lint/my-api-key.config
# Line: 1
# Fingerprint: /tmp/lint/my-api-key.config:generic-api-key:1
#
function LintCodebaseGitleaksStdoutParser() {
local STDOUT_PIPENAME="${1}" && shift
local LINTER_NAME="${1}" && shift
# shellcheck disable=SC2155
local ERRORS_FOUND=$( (grep "^File:[[:space:]]\+" | sort -u | wc -l) <"${STDOUT_PIPENAME}")
echo "${ERRORS_FOUND}" >"${STDOUT_PIPENAME}.return"
return 0
}
function ParallelLintCodebaseGitleaks() {
local FILE_TYPE="${1}" && shift
local LINTER_NAME="${1}" && shift
local LINTER_COMMAND="${1}" && shift
local TEST_CASE_RUN="${1}" && shift
local FILE_ARRAY=("$@")
local NUM_PROC="$(($(nproc) * 1))"
local FILES_PER_PROC="1" # no file batching support for gitleaks
local STDOUT_PARSER="LintCodebaseGitleaksStdoutParser"
local STDERR_PARSER="LintCodebaseBaseStderrParser"
info "Running EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}, TEST_CASE_RUN: ${TEST_CASE_RUN}"
local MODIFIED_LINTER_COMMAND="${LINTER_COMMAND}"
MODIFIED_LINTER_COMMAND=${MODIFIED_LINTER_COMMAND//--source/}
MODIFIED_LINTER_COMMAND=${MODIFIED_LINTER_COMMAND//-s/}
warn "Gitleaks output \"WRN leaks found: <number>\" is suppressed in parallel mode"
MODIFIED_LINTER_COMMAND=${MODIFIED_LINTER_COMMAND//--verbose/}
MODIFIED_LINTER_COMMAND=${MODIFIED_LINTER_COMMAND//-v/}
# shellcheck disable=SC2001
MODIFIED_LINTER_COMMAND=$(sed "s/\-\(-log-level\|l\) \(info\|warn\)//g" <<<"${MODIFIED_LINTER_COMMAND}")
MODIFIED_LINTER_COMMAND="${MODIFIED_LINTER_COMMAND} -v -l error -s"
MODIFIED_LINTER_COMMAND=$(tr -s ' ' <<<"${MODIFIED_LINTER_COMMAND}" | xargs)
debug "Linter command updated from: ${LINTER_COMMAND}"
debug "to: ${MODIFIED_LINTER_COMMAND}"
ParallelLintCodebaseImpl "${FILE_TYPE}" "${LINTER_NAME}" "${MODIFIED_LINTER_COMMAND}" "${TEST_CASE_RUN}" "${NUM_PROC}" "${FILES_PER_PROC}" "${STDOUT_PARSER}" "${STDERR_PARSER}" "${FILE_ARRAY[@]}"
info "Exiting EXPERIMENTAL parallel ${FILE_TYPE} LintCodebase on ${#FILE_ARRAY[@]} files. ERROR_FOUND: ${ERRORS_FOUND}. LINTER_NAME: ${LINTER_NAME}, LINTER_COMMAND: ${LINTER_COMMAND}"
return 0
}

View file

@ -119,18 +119,11 @@ function GetValidationInfo() {
##############################
# Validate Ansible Directory #
##############################
# No Value, need to default
if [ -z "${ANSIBLE_DIRECTORY}" ]; then
if [ "${TEST_CASE_RUN}" != "true" ]; then
ANSIBLE_DIRECTORY="${DEFAULT_ANSIBLE_DIRECTORY}"
debug "Setting Ansible directory to the default: ${DEFAULT_ANSIBLE_DIRECTORY}"
else
ANSIBLE_DIRECTORY="${DEFAULT_TEST_CASE_ANSIBLE_DIRECTORY}"
debug "Setting Ansible directory to the default for test cases: ${DEFAULT_TEST_CASE_ANSIBLE_DIRECTORY}. ANSIBLE_DIRECTORY: ${ANSIBLE_DIRECTORY}"
fi
debug "Setting Ansible directory to: ${ANSIBLE_DIRECTORY}"
ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/ansible"
debug "Set ANSIBLE_DIRECTORY to the default: ${ANSIBLE_DIRECTORY}"
else
debug "ANSIBLE_DIRECTORY before considering corner cases: ${ANSIBLE_DIRECTORY}"
# Check if first char is '/'
if [[ ${ANSIBLE_DIRECTORY:0:1} == "/" ]]; then
# Remove first char
@ -275,3 +268,18 @@ function CheckovConfigurationFileContainsDirectoryOption() {
return 1
fi
}
function WarnIfVariableIsSet() {
local INPUT_VARIABLE="${1}"
shift
local INPUT_VARIABLE_NAME="${1}"
if [ -n "${INPUT_VARIABLE:-}" ]; then
warn "${INPUT_VARIABLE_NAME} environment variable is set, it's deprecated, and super-linter will ignore it. Remove it from your configuration. This warning may turn in a fatal error in the future."
fi
}
function ValidateDeprecatedVariables() {
WarnIfVariableIsSet "${EXPERIMENTAL_BATCH_WORKER}" "EXPERIMENTAL_BATCH_WORKER"
WarnIfVariableIsSet "${VALIDATE_JSCPD_ALL_CODEBASE}" "VALIDATE_JSCPD_ALL_CODEBASE"
}

View file

@ -21,7 +21,6 @@ function LintCodebase() {
FILTER_REGEX_INCLUDE="${1}" && shift # Pull the variable and remove from array path (Example: */src/*,*/test/*)
FILTER_REGEX_EXCLUDE="${1}" && shift # Pull the variable and remove from array path (Example: */examples/*,*/test/*.test)
TEST_CASE_RUN="${1}" && shift # Flag for if running in test cases
EXPR_BATCH_WORKER="${1}" && shift # Flag for if running in experimental batch worker
FILE_ARRAY=("$@") # Array of files to validate (Example: ${FILE_ARRAY_JSON})
##########################
@ -86,23 +85,6 @@ function LintCodebase() {
info "----------------------------------------------"
info "----------------------------------------------"
# TODO: When testing in experimental batch mode, for implemented linters should filter out these files
# if [[ ${FILE} != *"${TEST_CASE_DIRECTORY}"* ]] && [ "${TEST_CASE_RUN}" == "true" ]; then
# debug "Skipping ${FILE} because it's not in the test case directory for ${FILE_TYPE}..."
# continue
# fi
# TODO: How to test $EXPR_BATCH_WORKER == true, now just skip it
if [ "$EXPR_BATCH_WORKER" == "true" ] && [ "${LINTER_NAME}" == "cfn-lint" ]; then
ParallelLintCodebaseCfnLint "${FILE_TYPE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${TEST_CASE_RUN}" "${FILE_ARRAY[@]}"
return 0
elif [ "$EXPR_BATCH_WORKER" == "true" ] && [ "${LINTER_NAME}" == "eslint" ]; then
ParallelLintCodebaseEslint "${FILE_TYPE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${TEST_CASE_RUN}" "${FILE_ARRAY[@]}"
return 0
elif [ "$EXPR_BATCH_WORKER" == "true" ] && [ "${LINTER_NAME}" == "gitleaks" ]; then
ParallelLintCodebaseGitleaks "${FILE_TYPE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${TEST_CASE_RUN}" "${FILE_ARRAY[@]}"
return 0
fi
##################
# Lint the files #
##################
@ -237,9 +219,8 @@ function LintCodebase() {
# Check for ansible #
#####################
if [[ ${FILE_TYPE} == "ANSIBLE" ]]; then
debug "ANSIBLE_DIRECTORY: ${ANSIBLE_DIRECTORY}, LINTER_COMMAND:${LINTER_COMMAND}, FILE: ${FILE}"
LINT_CMD=$(
cd "${ANSIBLE_DIRECTORY}" || exit
cd "${FILE}" || exit
# Don't pass the file to lint to enable ansible-lint autodetection mode.
# See https://ansible-lint.readthedocs.io/usage for details
${LINTER_COMMAND} 2>&1

View file

@ -57,11 +57,6 @@ source /action/lib/functions/validation.sh # Source the function script(s)
source /action/lib/functions/worker.sh # Source the function script(s)
# shellcheck source=/dev/null
source /action/lib/functions/setupSSH.sh # Source the function script(s)
# shellcheck source=/dev/null
for batch_worker_script in /action/lib/functions/experimental-batch-workers/*.sh; do
# shellcheck source=/dev/null
source "$batch_worker_script"
done
# Initialize RUN_LOCAL early because we need it for logging
DEFAULT_RUN_LOCAL='false'
@ -888,17 +883,6 @@ ConfigureGitSafeDirectories
########################################################
# Initialize variables that depend on GitHub variables #
########################################################
# shellcheck disable=SC2034 # Variable is referenced indirectly
DEFAULT_ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/ansible"
debug "DEFAULT_ANSIBLE_DIRECTORY: ${DEFAULT_ANSIBLE_DIRECTORY}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
DEFAULT_TEST_CASE_ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/ansible"
debug "DEFAULT_TEST_CASE_ANSIBLE_DIRECTORY: ${DEFAULT_TEST_CASE_ANSIBLE_DIRECTORY}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
DEFAULT_CHECKOV_TEST_CASE_DIRECTORY="${GITHUB_WORKSPACE}/${TEST_CASE_FOLDER}/checkov"
debug "DEFAULT_CHECKOV_TEST_CASE_DIRECTORY: ${DEFAULT_CHECKOV_TEST_CASE_DIRECTORY}"
TYPESCRIPT_STANDARD_TSCONFIG_FILE="${GITHUB_WORKSPACE}/${TYPESCRIPT_STANDARD_TSCONFIG_FILE:-"tsconfig.json"}"
debug "TYPESCRIPT_STANDARD_TSCONFIG_FILE: ${TYPESCRIPT_STANDARD_TSCONFIG_FILE}"
@ -916,6 +900,8 @@ else
debug "Skipped the validation of the local Git environment because we don't depend on it."
fi
ValidateDeprecatedVariables
#################################
# Get the linter rules location #
#################################
@ -1067,15 +1053,10 @@ debug "---------------------------------------------"
#################################
CheckSSLCert
# Check if we need to lint the whole codebase with JSCPD
VALIDATE_JSCPD_ALL_CODEBASE="${VALIDATE_JSCPD_ALL_CODEBASE:-"false"}"
export VALIDATE_JSCPD_ALL_CODEBASE
debug "VALIDATE_JSCPD_ALL_CODEBASE: ${VALIDATE_JSCPD_ALL_CODEBASE}"
###########################################
# Build the list of files for each linter #
###########################################
BuildFileList "${VALIDATE_ALL_CODEBASE}" "${TEST_CASE_RUN}" "${ANSIBLE_DIRECTORY}"
BuildFileList "${VALIDATE_ALL_CODEBASE}" "${TEST_CASE_RUN}"
#####################################
# Run additional Installs as needed #
@ -1097,13 +1078,6 @@ debug "ENV:"
debug "${PRINTENV}"
debug "------------------------------------"
if [ "${EXPERIMENTAL_BATCH_WORKER}" == "true" ]; then
# we have showed citation once, so every other parallel call will use --will-cite
info parallel --citation
else
EXPERIMENTAL_BATCH_WORKER="false"
fi
endGitHubActionsLogGroup "${SUPER_LINTER_INITIALIZATION_LOG_GROUP_TITLE}"
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
@ -1154,7 +1128,7 @@ for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
debug "${FILE_ARRAY_VARIABLE_NAME} file array contents: ${!LANGUAGE_FILE_ARRAY}"
debug "Invoking ${LINTER_NAME} linter. TEST_CASE_RUN: ${TEST_CASE_RUN}"
LintCodebase "${LANGUAGE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${FILTER_REGEX_INCLUDE}" "${FILTER_REGEX_EXCLUDE}" "${TEST_CASE_RUN}" "${EXPERIMENTAL_BATCH_WORKER}" "${!LANGUAGE_FILE_ARRAY}"
LintCodebase "${LANGUAGE}" "${LINTER_NAME}" "${LINTER_COMMAND}" "${FILTER_REGEX_INCLUDE}" "${FILTER_REGEX_EXCLUDE}" "${TEST_CASE_RUN}" "${!LANGUAGE_FILE_ARRAY}"
fi
endGitHubActionsLogGroup "${LANGUAGE}"
done

View file

@ -15,9 +15,9 @@ language they refer to.
The name of each test case denotes its nature:
- Test cases that are expected to pass validation contain the `good` string in
their file name, or path. Example: `markdown_good_5.md`
their filename, or path. Example: `markdown_good_5.md`
- Test cases that are expected to fail validation contain the `bad` string in
their file name, or path. Example: `markdown_bad_5.md`
their filename, or path. Example: `markdown_bad_5.md`
## Notes about specific tests
@ -26,7 +26,7 @@ In this section, we explain the peculiarities of certain test cases.
### SQL Fluff test cases
From version 0.12.0 SQLFluff requires a dialect to be set, and no longer sets a
default. This can be provided as a command line argument, or a `.sqlfluff`
default. This can be provided as a command-line argument, or a `.sqlfluff`
config file (either in the usualy place for SQLFluff config files, or within the
folder containg the SQL).

View file

@ -0,0 +1,8 @@
---
- name: Remove temp files
become: true
file:
path: "{{ item }}"
state: absent
with_items:
- "/tmp/test-1"

View file

@ -0,0 +1,11 @@
---
- name: Test playbook
hosts: all
tasks:
- name: Remove temp files
become: true
ansible.builtin.file:
path: "{{ item }}"
state: absent
with_items:
- "/tmp/test-1"

View file

@ -1,5 +0,0 @@
---
all:
hosts:
test.example.com: null
...

View file

@ -1,9 +0,0 @@
---
- name: Configure the GHE Instance
hosts: github_primary
vars:
demo_github_initial_user: "{{ hostvars['localhost'].local_user }}"
github_host: "{{ hostvars['github_primary'].ansible_host }}"
probot_server_ip: "{{ hostvars['backup-utils'].ansible_host }}"
roles:
- role: ghe_initialize

View file

@ -1,4 +0,0 @@
---
collections:
- ansible.posix
...

View file

@ -1,182 +0,0 @@
---
##########################################
##########################################
## Standard Variables for GHE Configure ##
##########################################
##########################################
## These variables will be the defaults. If you want to override them,
## then change them in 'vars/main.yml' instead of here
github_admin_password: U53r1234
github_initial_user_password: U53r1234
github_host: github.service
github_admin_port: 8443
#####################
# Default Rate Vars #
#####################
api_rate_limiting_enabled: "true"
api_rate_limiting_unauthenticated_rate_limit: "60"
api_rate_limiting_default_rate_limit: "5000"
api_rate_limiting_search_unauthenticated_rate_limit: "10"
api_rate_limiting_search_default_rate_limit: "30"
api_rate_limiting_lfs_unauthenticated_rate_limit: "100"
api_rate_limiting_lfs_default_rate_limit: "3000"
api_rate_limiting_graphql_unauthenticated_rate_limit: "0"
api_rate_limiting_graphql_default_rate_limit: "5000"
######################
# Default Abuse Vars #
######################
abuse_rate_limiting_enabled: "true"
abuse_rate_limiting_requests_per_minute: "900"
abuse_rate_limiting_cpu_millis_per_minute: "90000"
abuse_rate_limiting_search_cpu_millis_per_minute: "7500"
####################
# Default Cas Vars #
####################
cas_url: "null"
#########################
# Default Collectd Vars #
#########################
collectd_enabled: "true"
collectd_server: "metrics.service"
collectd_port: "25826"
collectd_encryption: "null"
collectd_username: "null"
collectd_password: "null"
#####################
# Default Core Vars #
#####################
core_private_mode: "true"
core_public_pages: "false"
core_subdomain_isolation: "false"
core_signup_enabled: "false"
core_github_hostname: "null"
core_http_proxy: "null"
core_http_noproxy: "null"
core_builtin_auth_fallback: "false"
core_expire_sessions: "false"
core_package_version: "null"
#######################
# Default GitHub Vars #
#######################
github_ssl_enabled: "true"
github_ssl_tls_mode: "tlsv12"
github_ssl_cert: "null"
github_ssl_key: "null"
#########################
# Default Governor Vars #
#########################
governor_quotas_enabled: "false"
governor_limit_user: "null"
governor_limit_network: "null"
#####################
# Default LDAP Vars #
#####################
ldap_host: "null"
ldap_port: "389"
ldap_method: "None"
ldap_base_dn: "dc=demo,dc=github,dc=local"
ldap_bind_dn: "cn=admin,dc=demo,dc=github,dc=local"
ldap_password: "U53r1234"
ldap_user_groups: "null"
ldap_admin_group: "Autobots"
ldap_user_sync_emails: "true"
ldap_user_sync_keys: "false"
ldap_user_sync_gpg_keys: "false"
ldap_user_sync_interval: "1"
ldap_team_sync_interval: "1"
ldap_sync_enabled: "true"
ldap_profile_uid: "uid"
ldap_profile_name: "displayName"
ldap_profile_mail: "mail"
ldap_profile_key: "null"
ldap_profile_gpg_key: "null"
#############################
# Default Loadbalancer Vars #
#############################
loadbalancer_http_forward: "false"
loadbalancer_proxy_protocol: "false"
########################
# Default Mapping Vars #
########################
mapping_enabled: "false"
mapping_tileserver: "null"
mapping_basemap: "null"
mapping_token: "null"
####################
# Default NTP Vars #
####################
ntp_primary_server: "0.ubuntu.pool.ntp.org"
ntp_secondary_server: "1.ubuntu.pool.ntp.org"
##########################
# Default GHE Pages Vars #
##########################
pages_enabled: "true"
#####################
# Default SAML Vars #
#####################
saml_sso_url: "null"
saml_certificate: "null"
saml_certificate_path: "/data/user/common/idp.crt"
saml_issuer: "null"
saml_name_id_format: "persistent"
saml_idp_initiated_sso: "false"
saml_disable_admin_demote: "false"
saml_signature_method: "rsa-sha256"
saml_digest_method: "sha256"
saml_username_attribute: "null"
saml_full_name_attribute: "full_name"
saml_emails_attribute: "emails"
saml_ssh_keys_attribute: "public_keys"
saml_gpg_keys_attribute: "gpg_keys"
#####################
# Default SMTP Vars #
#####################
smtp_enabled: "false"
smtp_address: "null"
smtp_authentication: "null"
smtp_port: "0"
smtp_domain: "null"
smtp_username: "null"
smtp_user_name: "null"
smtp_password: "null"
smtp_support_address: it.broke@github.com
smtp_support_address_type: email
smtp_noreply_address: "noreply@test.github.local"
smtp_discard_to_noreply_address: "false"
#####################
# Default SNMP Vars #
#####################
snmp_enabled: "true"
snmp_version: "2"
snmp_community: "public"
snmp_users: "null"
#######################
# Default Syslog Vars #
#######################
syslog_enabled: "false"
syslog_server: "null"
syslog_protocol_name: "udp"
syslog_tls_enabled: "false"
syslog_cert: "null"
#######################
# Default Splunk Vars #
#######################
splunk_host: splunk.service
splunk_port: 9997

View file

@ -1,11 +0,0 @@
{
"private_mode": false,
"signup_enabled": true,
"github_hostname": "github-test.local",
"github_ssl": {
"enabled": false,
"cert": null,
"key": null
},
"auth_mode": "default"
}

View file

@ -1,873 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
61383339303139386235623338336365616565666363313538613164656664333962656164336231
3032323336636539373430383035623736623930613232330a326364356264386533643031383038
38636131363364653962346261383335326561366136373663333532313831323764646261353131
6534663063346261660a343163306561633862333635666632373234366464663265316334323261
61636536666335333931343236393562653261353664383130336564626561313932303564336434
34366261313637653136373261313337626365366339383330303866646263626435373336666564
35613763643334643362316235613130366664306336323939343331313733626135346266613233
33653536616164623939323161313337666132336233373561616636636364653734303430303033
32336466353332393664353536376363643965613665356633366165316138623437373262666365
63383731316665623362383831393663343736653465363839613437363765393137393635653232
33633132663837383138333330303130383232316566633363653138623364363664313535646132
32323039353361306361626634613332336637313066353330396465356232346136373138346235
32666532356433666430616230613464613332656661356435313430613731333962613464666365
30376138333337613538366366616264326236303932623336313033363061643037346338633731
63663134316238316330353865613938623936386563383532303137323864353061386164333430
30346532383539373031616162643233646331623535333863363931663131393865303566336633
35353439353239623830323936373363646639656532623136346335636362373937616165343331
36613038653666376336663832626333643339373933326563366135366134326563336233303261
35313263363065386562333662313032613632323235333632313332303563643336303762303363
64303765356436386465316665633832356264393033633862353065666130643731323739353133
37336633653535313639326438376462366232663531636561663136653366363865346131623039
34646234323736303233656537653132666636373264333662373635626434666530316339303363
63323163333339323062613763626337643835303665646536666261616435663761383461623731
65323865316261323732316164326438646635643634656636386563383732363335343762313834
66343934393063343730613734316166343966366362666236663362663731396531643366363531
37386363613266353537313366323863366163383233343961323037636235643538313230383330
34636164313061393433316263613632626665653432366232313635653864646136366631333938
31393135303663323765333262353338386461356137366335643034616166643862316134633666
64383930383137393666386466626630346165643962313233656635646331393062373830656337
33306538653066633061616331326234393865313831653864663832323663616631373836636236
66353739323434636637316633663231616239326465373633626432653339393933313839666464
64326238373862303937643635373835386339393264386362346334626538613533336466616435
37653536313033643134316636653166346461323965653530393637366564663038333534623830
32386330323962646631316235373634393965356535626633346666303532343938343334366361
36636638633966316362306362626535306662303361653836643532656339653838313063313232
62653937653465336163366630353236656230343330376636336539346630353765396636346265
63333761626361616137316230323966333132386433333365363961346464656432386461373037
38303430333336626137623337646633386334626438363939653734393135376538646433623633
32663963393761643666623834643162373164353038666533653439343332346563613662356663
31636562383662623138613432666565643331396133353232663634333464303462393663373130
38383932363264616666393633383239613262666634653831313261616665356336613839323439
32333764363630656165633339633434623338363065343437613134353435303563333839613264
34646565346330323036376436623933343037383065353538623764366130376639323535356461
64363639396362346639636235306565663066366564386337666664633034323761373032646233
36616162363335353562366434396664636664643034336264633633366533653462303263323965
34636633653463363565636536353039303962316534636530353031343966356635643262343534
30373466666565396135653630373830616432343863376265646438643265353337633530343637
33313062626235646630353637656466643239323466653731333531633063373333393633653038
39336461656634373533376366383237366364366434353163633263636163633036376138393162
61636537653564663634343534616431356635663061613036353338613234663634633561616238
33306534656130633537383634653763303736373035363466313138613762653139386366373933
61303335643063663063333234363264653962323939656566633533643535366239313335376165
31646537373933366239613063666636313535393765363165373539626531633062656439313235
34383738316366306563623031303761393265343366643264303564356339376437643963643035
34303035386539353435626566306133336335613534666462303537373764643836643735643034
30373237363330633963656337346638346463636439383732313663663636653763353666306562
37633330326664616166353330343264303565396438616463656361656532666130636334366562
30363630323230373036636135653533326661333836613934616466346564376161626131623337
31306338623534613662313233616134346330343561306438646461613165386166636136633132
62396337613265616530613061653762383565393434323931633330616530643833336136623034
34326661343464376364613132316531393134613335343162396238656562346162393038376166
39636331346235336465633237396637653038316261333565616439656633636532663137623633
31393463303331343734313465653337343564303133633034303466643766626630333333396337
66646234346435313535343536333865316639336230373732616531363337316361356635663066
61366163643364336339643133633339313831356164336566613431663832346133626139383130
64633933396462666633353661643737636164633930323165653831623435653539616630353036
32336535313635313066376338343434396631653365356264313661366331363839363263356531
37323663363863636134333531633766623637653664316333626333616333356466663230323737
30653138323333336661316537643831623564646133313636313934383061386235346330623632
61396536336461356632356434346337363538646133393932626533643335313862376436366336
64636634396332363639383866656662623564306435366564383936613665306338383264623635
37346165323139313930323838633033663536616361306664653231396465396130613561343733
38313039353930313263653930643338653438663965643435663864326336386437653333376362
38653962363164326131363235363736633534373362646532333661326638623363353435366661
37353665636437386435633666373836356566333733393732383739316531623437386336366562
64656336396139303766363930663430626330613265363238336538373538643434383263303434
64633532316331306534613134613035396132386463313063383062626133656135373131393335
37386161666365323039306238623533653131363933663035333065363535346262643466373131
66303736333038653233633932373061316161373061313964656332336637636237333834373763
30366336613233343461653134386263383331323935666363323463663161636565333037633262
66363539656461346363333562393963613462386531616337353132623962393562336661383438
33666230663034316532633766643934356461353262643635646138366165323966316637383436
32393065393830646637613539633237663232613234626465376563373738396263313361663532
64613461326366363637613665303963643862316136636333313066336562656133663261373231
36663234373166613864353130663761353262396232336563363534396135373463623761653839
61613863373834306365396539333839626133343239353232663335313237636638626536373466
36353065616433383165316465643362623937363337323437336566623665353032336564346161
37323161653432306532366439383231343936626661323161643430633065373664333538343032
61373036343839306539326164323737363037646237313666646366303138303565383663363239
35643736303536646436343330316661663061303261636338633237383935633961313833396532
31313732613939623661396336376435643030336263316639353034616530346566386536643235
35613765666232623639363530346166643736643333333564356631623635636233313335346564
61346232393833326562613834383132373366333965663061306438633737353037353261346663
33363062633366363634333139326532363630383333353565396435353565313564623534613338
36666536383932626664353361313333343135346639626336343663323238376336663561316362
64303433303162363863393864333462353766646232353565646665653936623261643639646264
38613031326362623039326331633161666231646139666530326238623733653538376232313663
32356630313162333065356532326463623661373266386338383531313330653463353036363965
61653935363464663764646661656136356165333237373233346236613165323662373565343532
65383935323033383039623938366530306266633763643239386435303037356466653565386533
36313764646561343737346335363031386634333961316333633038636532336161376562633064
65323139333533666464656239356234363135666266663466656461613732623536656565666632
61616435653732663537353066363664626366303064363039356337353431376136653738343462
62663431363665636166393166393334383332623635666562313037363965353664373965316265
31383436306663623463336261363337663538326336623564356264376434653130343535313762
30626137323838313264353030356265626233373236623262313661333833363139633639363664
31393638303738353030373639393931656534376131613061353162623364643732656232333436
34633238383331353366323663623238636237326134356665646533646638333166366633383231
39643531616264616133386431326234323731366132393033316638366538626531303735363066
38623662633438396565626535616361396264653465343939653134656230313062306232373930
33656139616361343432643835393039353761313334343663306263626164386339353564363135
63633463353231636665323433363038623031336463393034616538346638343863663530663932
61363065303031663463343762306238303765313230373738336661396465373061383636656265
37623535393938383839306466326137306361643962646166653836303730613665323165336665
34316439326332336339373236393264636536653036363135396166663565383864613235373061
31613663313866386531343361633262346637646363653031343637336563396638396530393237
36383635303633306438623136356638613465353439303730313031633338336631653264396138
31373865646335346331383838356634373737363737316130663931383635396235353561393137
63336365616466363766616532376462323336656166396664353966623562306363313463303234
61626663346563333162326366666361643330353439376631636233343466353763613866366461
61336636646331646231313561613436666134613934353938636330306261623132306166653838
30306664613962623336363836636232303461303333633030373065336664323336353134313733
32346531343535316436353663623936393065653132653337393364383830323538323332393536
32353937343335393761316539666438306262646131356563333238613064343764653832623133
66333365343331346635636630353932653837343264646165333535393664386161343337656138
62353962393866626336383264396331306637633162663932623831373535303939663031636633
61663761313732666464643361653635383032313932346466636634316431613663663163646133
33363138313861343965376637386331663339616562383262313934353032616264653337323933
35356666653134343162333634313430346437303262613562393839616238306239333339353630
38653531636536333665303766363866656533303562336135376236643931316563333362636164
63653564633362613465393562326637306538313936386231393663616164656163393438376436
65383636393230363963336131353634393265396461626131616233666663666466326234326331
61616436623166373232383131663663646237396563663335383935366537376330653462626366
31633036306337666439633931623038393330316633623533306238303832353932366235633339
39396234356634373339356131353832333832356263356366663133336236363337653631636132
65316638633831626531343464666636313764313134363931303365363862306439366138666138
37323639376566356338643965343464313236626239616438613964363930653030333938633538
30616636393236336437313436313638303062636334356266383537346435386438326635376232
35373965613462666331616337303333323836666532626465653933373562643834306237633830
65303835363266613235613136656132396631326237643130336338386230373061326333343464
37663565636330323765646536623961643832303030333564643664663030653232656534366162
33316439646132636132323933623635636536666263636465336665633935643830386130356662
35343833656330663139333065393330626533663137613734666366643962376131343236363831
61636464643439613238363837333130656236363433303461363566396536633430323837326238
63333263333836313535643439313865393437616431643230333732393036663833613832323233
34303631323038653139396634633630346163363262393662313865613635656130626531343164
33333437333037383133636238323364373035393563366331663333633133633161393239626264
35626236323961626636646466663061653736376465393965636635663637313537323733613533
37376535663163353266336565643363353936353537373938306639313765646438353730386631
61386334346135613333666261333430366263633665646234336233626561323362626337306639
36653962313037343837396235663530346231353565326233396565623337653831386530333031
64656561663534303262356363383035376436366562643430643162616264656430383139346663
62393735343639303638663831393330336234393438313862393839376636636563396634386561
34363064663036303633613365393164333433636366393838373939303562333135613864316261
32326333653337366361303439373464303961303164626461353533383263326665623465353937
38313536353932613038633561656530663665626637626232303662663565393236636264343334
35393838306535363735386464323164363937326530656561613235393434653864646338393135
31356537363364643135653936363762646232343663653636366131383862353264313333373863
66373735386334643764373237306636366132373161353134343836663761313334366334356633
36646537393034366336386133643338326635303538653964366164316161366261633562343630
62346461316239346661336662343137373039656339353534333437626466663161323366326535
31373338636462663130613232666334333434643463383665396537656332623338363062326134
64323761643366626233336163356638383665363139653439356438633666313432646237666233
37613033613731323661663137666532333462636166303863373761633061613764373232343666
62646232656432383831646361316663323964343263363065383136393737663430643234333130
31303666666262396638616136393765383335623130326630353037303335376266336563343738
65663163646563666533316231643334363133366335363661336466333835656436333961313431
39356364313863343431646633646636336236386661643032636139386662613266336633653363
39306264633766346532343635633231356238376533396533363632376438336164383463376630
37333238313334306230316363616131326333616333353037346262656666656333623736323134
33326663383237616663666339653230613034623831303362653330646634613766613333663762
66356431343739303962663932316435643538356165333564646530373763333636333332313033
32376135336439336661396564306432393763653835366664353331336537643535396237633363
33343064346130616135633262643631636233373930393531303739653234393566396132383361
66333835363763303330613833333532353933633964343137633065633266656532313738316661
64653564643333393164313565643035663431323535353330613062656531666361316638366262
65386233376661383035373230343363616663653033313036353730373131306666633237343032
36353239623839636664643531363561663636366563373638303030363832613430343134653662
37376131383238653038396263313364396233316232363665353634633734633462656561616631
37323566306135346335623733626637356531313034363437356364363337353730363436363836
38666637363263626635313836626630633262313332356230393733323832303237376364313764
32383637366139636462633834333066303637616631306439633931353534323830663538383664
33323861643431363065363061326366333534636135613738393863633332366461663132633232
66643764646337613533636661643637326533633832346230386465616465643366643166333935
66653230633635663439386366623932316365653539656462363531653264336437393035393231
38336135343065643736363337376138663063663131636562623036353366323236616466633536
36313266653564396436383864316464373431666533306236326237363632393236663062393231
63386565363865623734663738396665656330346137666665393564323137613131303965346538
34336662626164306139353762373365323932633436303339366236373232393238396231373038
61346266666239663339303431616233643034623434653132316234373136623532383832666330
36663539306563303931616338356430336438336237376234633238633662396134363262636233
34383639626533333034636637356434383466343530356337326264303531653263616462643961
37393334363862366138323437393139333730373838653764353761383061656661636665633135
34383036356663353938346530643035623939316134663138663939656132616461396339636539
65346263316263613137343539343232353833613134333863366237373463326466316137366166
37306632346363636137303061613132373263363062653534303131323539666536303230633637
66393931393436306635356139663832653166383337656262383339396331346230633163616461
61386635643034656538323638623738613534363932353233633330323033623530653137313361
30643331393538346433653933366232356364306264353337633431303662303765623333396463
65363730653933323431323961363839623837333964333930633166663936353062623366333331
31363164623032363333643430366530343237633063666564623630643362656164393635326530
31646366363962656333323533383835363734666166653561363561333430666233356562353630
64393731336535343435313164353532333132623338376236346230393966333164616537323231
34653962643337333961633663373333343435326261343032633662623239316364653839303130
65363062656336376661326334306161663238626238633537613437386632356638323064373866
32383464313064326533396663316666646134363534386163313366356664396433313632363236
32396136396338616237333630336130313036653734646435393539373630643264646633386232
66653833363962663633396331643530333563383463313862656535393932363039306131353732
31613934616438333062383033623765386437363235393462333264376133353030623534313266
39383830393631386538323637303365323665613936373237393639626239346666373866363662
37616231373864303462616534336662353761653330326163656230346564353237646637653734
30306133393039633566303332626164393235626163333133343133333762333461343835366239
62373066333866653730633030316234366234353431363430396531666636373539333135656334
34383735353966663166343732633938613230303362363861386363346330336139363932653436
65303162643331343836613766346536323236366462623363613963613839663237383030393561
65373762323265396433633738626530366363636630346132333066383363353834313333303432
34393239323336616434633731333861346332663939386561343931376634346561613939613934
65666338663434326337313237623931353937336164666366306662333664396266666662303662
38333532653839663762626431613437386564333462653665626231653737353039663330396135
33373039353632656361613266333932383262396265326638376163316432643362636336653439
38353330303031313131376439616131396330363538663734633362323239346138663539326665
33323437323530653264613165636635353131336538623864393033353132666338333832653561
38333965386433373432366361666233396337643861663837636633623865383134313030343064
33333035616161383039353839313438363733353535323635623264363666346630303431643038
33643938666337353262346533643463313465303964313736333435613835386365373232636465
34656434316532633437666439393732353965366637393165363062623665633035636336646439
31316631313733303030333333613935383961613839623035363235643539646431646638363766
30346133393838373439643563646161343265373334316161383631326663623935623437343865
31353232653863316365393439336634396261373336643765613566636563373733303634626366
34613935376463373834353931643630336630393438653238666561323334653338323936356630
63386262393439313731346262663766626137386235633839323562323561623966663162353062
38623263393164643733646332376365306638303838356461323335653536646439373334393562
35646435333061326439383966336535373936373134303265366433653330346665613762316537
65346363626666656261343761363838616432303264326133396234653461326632393339376665
35663235373562383733343034396538653261646539376436356534383066646435303863336464
36373330623138333739653435363261386165633361336439343539383939636463616163633638
31393937653435323833666430346136353630313433306433356630366464313530613365663931
38656136636430616139626235326230323731333164333466366164636439303063643732346633
62303233643261656665306538356238333031313138363338643738353134613630343162326639
37326262303432663638626331343038633835303231373532386165643831633337363737663736
38616233643461326539353638363039316638616530633435643839306263623463376563366161
33353365636130643033356330653432633433373232383137633931313332373362326135376435
34656336366163386335323738343763653838343838303931643437373366646133353738666236
65343661363161393165336632306462616137613061366636303764356435613738653036313834
38326639663361376237386233363265333261646336653763316532353934353037323130633266
38346266323936373338636666333832613733346135616336323735383963643830656439636533
37306530356532383864383432616130393534356432636663633936613631366566363939633236
64376133616333306430653161663863663838373634333437383031623939636665313030666537
64396632366264646434616334323036613664333065303437396563666339613232336362656136
39376532366132306238316434373066396336306132633631323731633364326233356334323936
35623938353762643730643438663235636464663662643162326132373139373065343632396166
63643933373531333161323864376332323663363833353434363763353133313566323337636332
33396165343962383236356332616631643235306265393932656632373138336263313562323963
38373431623236383866366631333031643735316163336332353033396435333762636331646538
30343034616235666162376338383263373139386438303836653935303639383765643761643837
35323336613164343765336138356134613166383339323865343762663461623339656533663939
66653436353630623032626439386565303237333366623662336436326533646334313263356366
32313962373333646664346438363931363864616636326531313733353632663539343865666665
38373038616338623632303133346466313339643632663261313164363366393465623036333138
65376330386266383035623564653064636439323664366237616237613633393331356430333432
34656662313465303434623466666566663538666464646133653530656166373230373865653939
63336138333434343463396335663230303865393836663263346463633865383966653232636262
32613362613266643134356637363338313563363662643135653037633433383265363535353336
39353661663234636263613039303666333135393536396666663532366530303665326537306564
39336231663135656238653761343235623063643637343565363866656133366266373764333430
31303666393231353238376166656264383466633038643338633737346435653736376133383636
38333238363861353939303431653432633836373331663330623838373736326166373461363864
39363438633236386563356635366265386363323462353435633330386265323632643234643436
38326363323830313631616636616633396532393232383438646465626239343661313030326265
62643165353963643834653534636364613165323965653732336261633063323931663666303765
30306262626366306238646632326566326663346539376333376535666266373038663633656138
34663566343231613733333931393138366339323936646331336232363730376331643963623135
63343466343132313864333736323435303835383462666332316631323761323435623231643939
38643562353936616434356164626539376335393231306164386135633261383935316366306434
34303662376130303436623036636230303830383464616336393833393239396537646231656336
30616361646634366634653336626133373136663562353630653862313731383337326230613965
35383238363335373165653562656535303764316237316537346133616235393961663238333735
38633536386130303832346635393438363061313862343538333061323063623538333730646332
30363132323235303231643331383263343666646535363532313366396266646266373039633137
61613134313930323837336638333337323965386635643338376337626135376536643332643037
39313931343038653439353734303239346132383763633833616665336361336231666437346330
65346466663233363761393037633663346464313963363661366464393130313739323661633634
64383733316635383062616465383765663130376565636262363439623763633862303731323665
63333630343064396137616437303937336234336634373264303433643564343264626561393365
38343230336662333638623038646536373131326163376232636439616332363864316434653530
61663239366232393861363535336533326462633331633739613333616538383833373838323134
62313537343865366536363436373365346134333730303936663438333737643830303238616162
34623466653963363831366361393739373431666464613933383761396662346438666234353236
35303335613931633861326236356533336532623038643238336366643362363936393863616264
66353435343565353037643361326630616464366664633731326161656334383764643034396361
63613862366437353035333932306530383738303866623535353135313537326433376231653134
34636332316565383237616532363735653962636361356466366335613934326566323230616232
36356135626233323863386662313838356339343337353663333161313138363566306134386263
37313439613161366639323338373839666130656138663437373830356264316632653866663633
37366534633463636136643438333466333737613763393338306236303430633139373763373563
63653561656137353933333832653735333030366661663537636138306164626662343866333230
34333131643762396465333632366135393364333037623932656134323733636634646431636435
31626334393836373730643333393832613162343332653362623832323038626461323062376238
64346362353666393563333733373462616630356265303765343939323431353834366137306463
38333266393233333933396630353065616363626162383737373237663036323235346636373739
65303262393965326138656536616436376132316530313732386536336461386665633434343165
37313531363633356130653539323364663039386338313434306561353632323766316363663162
32366665616136636533333765613566333334356565623062303439643964653266356534636531
36366462306639326239316438656333386238646334636238323038666566396135613363363239
61396630663662323134363233666564396163646666633336306266613262313061643730333331
33303036313638613137656630626262326338636361363265663936636462363732663833346366
62656162356465643939636434323061333861343838626533393237663431623563346134353562
39633632326130343732306538353761626665346236313037393039643366613634663365343666
61653739373837666334393539306663636562373531383435653932646635386636323066316330
65646265393038336664383539363536383534346562326262333565303764636533663966643463
36366335646432313161366265643231326238303930653031386166633939613831363262343465
35356634366631333937343161353934373962303862626463613564323334376666383630333231
65383334656439646239383864323535396365316263376537373832636134646132646665396137
39323266343938656137363266613239346563613761343532313735353663356264333165623662
62333334333163326161646662353963616364386361653964653735663231373861623134663133
38316262343937663830396437386439353934326166663231353563626636663561363136333066
30316434343965393437343565373865326537653765396430383962323263356537383331643264
66306465636162363366663235323530633133396234613135366664313739313838623236643330
36623136626264326133343537396663303333636637303435393638383166663962366236653064
64666133333939376331336662356164663265653237636233383532323437303066363765316262
62376464653431663463336638613134376337303166336534663362623962363638663531346433
32353536646230333463663938303438396339656436313332333936313434633364363839666535
31353064653135633662306466353362613133373239616234363765343433356537656330666539
30373036393063623439623465393864623030633539313332383736323430383764396337303834
32626665323737633764383835643261623535313366376333306130363733356436613335653862
64383364663633303566316164313438643236633930636166353233386638646139653339646363
63326266313139336635626130633135643936356463656661663866393833353236343739393939
63633861313666376665643730393361396437666236333039383630386535316665656561366538
65363664373363363665306261306466333161653533373262313563623062653464313037396664
66373465346363373131656234326633306434353630333531343838646431316233343830336362
36663264613166303330393332356230626631613338633934373532336565343264376661346134
37666666653439326234616439616637396434633333623737383563613832653130393662363665
31363866613832383636373434326162383535363133663732656665356336313039636432303439
34396137666337303338373936353230386338386631633534306364323236313739363636626431
30386132653435383062376635376162366162643335303864396230366431386366386262653435
32303037636337396663626564626336333033393539393130643162306166323236646561303833
38323965363061396534623761663631343938626661306633366565653735333865626166353663
34663731323735376662326465623730366662373436396266383636616633616230616463656335
38643564353738643461383437363139366431653438306632356262633031623930626166626332
61646136656539653638613665626566613039373836313933656636373931313762306466663265
38363765313135633931376335323364616530366366623931363834653234636530333131303032
65383735643234626566323266363238386564636263393564366235346333303733323132656239
63326332613838666161383861613037373965646332656565666566336338633232653161346131
62303039373264666239623962633436313438643030633236333539653936363432376461633835
30636264356237666532653338373031616236366264383831656561363230636535616337393537
34363536336361353733323030383131626564663236303161306332303736333034326366326265
35363963353163653065363633333364666664393631316239383331316462346537376263633630
31613631653538313366653733363163383365383665633432656532613633386235383761636665
39663061313761313233666532633366613736653766313166326234373766343532393735653664
32363965633434363130386664303663643534373236373838313065363634313664376137386130
62326432306461663630636231663735613535623834333931343664633536396235313531333034
62346135303939366435336664346539616436303465316439643932666433653164366163303435
65633064663339613032376462643566313535356464363861646561383437633463666633646431
32333765653363343436356663323439383030613762653566623832386464303931623465396433
62323961316662376265626637623630626463376530633834623461376563323033616363613637
36663165666461306666666338303230663937613036643066343665323465653337366462303234
37663330643431396537326162353838386437323536303431613664656464613261303334336234
39323530306338373132643666333266626330613661316632623732316636323731383338376166
37333665323961653939663066346432303134366139326563653363303337613638613334643935
33386133363236316638306235323737346231353139346562393639393032366638303237303234
34346262346535623566636338663765643961616131336462636534663064313134663232346130
62646538626366643466646338626464313838376239396462663166336337306166656565346433
63656265616166653461656263353662303066373864623061336365326666346332653233396530
38373366303665383133613063303736303663323338356532623139303733343962356364383134
65643834376531333261643835623264636664383431656664303961343834663665646366666361
35313463376263363263303664393636313231366261303738376134376236333764353633333836
64326565643136306138663262363232333066306162363363383230646461336163333431303963
62613937326132666638386236333465393438336666303865396266383738396366303236626665
62343732303266356432343164316432663466663335383433336632396364616165326433363266
33636530303735323462346135393939306535383566346530643862336232653134383165353734
31626363353639336438363465353565303635313835626538393566623861383263646131313765
38633733303162623363363130383637663366643666663038633537393261333166363963303837
34653331323862306464313064363964633761383361336362316334323562323730326563643636
62363035356564346361633030613064333663303933366134613764626534383830353461626462
30653830663730626230363231616339383738363030393865363835633738333236313538636137
35373937383837323566353461623936373963666437646334353066373266386435356434626463
30663835666235636362663332636538363639393439613966373366303062336461303966643664
33366161633639333661653765363561393564363364326265656262393030343531356534393038
61336264646132306466396637346136623231336631646635306264373166343864353662346630
34316630383432383664366334343434396435636532393461616565623436396566333731663937
35383139633966343566393962356132383232636564363338663066386339373538336166343965
62656436646136353833623339323163643131653863383866626364663432303930643835346238
65386662663263376536373731376638356366383965313863666538343632623334306531343337
31613465343662623333373865373564303935376434353530316665643932643234633834383331
37633534396665666564363361326139353939363861643530383231316231326232613038333930
63366463373862626338626531326137376265616430303961383239343264343936656461613339
35343766393235653563653831326530623761396665393739666362393330646134623961373233
35396634363063366163643334646135346664653737623632646535393861393264656263336639
32356263623366303566356430313439623065393366636463653633343736376234326266656632
62356464376530656533646237656339313161393165353431633462363062336264616565323831
32323135623938663839633433386432386530656238613464333731636463393964313931613934
36323035336532626232333762653136323631373538316536393364366537336265326334336135
30306332343533613163626531366638366533613163303833313561623333633836353934643562
64386666633335643731613832656230343930336435343930396633353962663630633035346431
33333361313336306135616539643037656262383937323437613332626333323234313861323165
62343338666466346266613433303735663437356462333133373330653963643364666536376263
35333537313762313037633839313130373239376336376431396635373463643164666635353432
64303364653130666333666361356531343465306462373032353433653061626335393437303332
36663962323063646663393966316236616663623734383030653239346533393766663861363739
31396630356264383338363364313862366161663966306135643639343362343466396136633232
30323231383061326134616366353631656462396166343938393463383539633039393364316362
63326161313137623964336663636637616530373262313031643064633631623239373736623461
39626435376238626130383931333665383935383765343630383135336631383336366465306136
64376230386235363138636130333930653039346332383266643463613531663530333930396339
34653961613035633231373833346638663533366335613139393365303163613036626233363462
66316235323236636565326230376133316137373131643166663135633465303636333962616539
33323033316661663238653433616239386633356439363365333039636136363265636539643264
32616639383462373639626238396261313037306239323434336664623261346162373039373662
37626661306365653039313939646164633565386533396136663330646431393030366333356264
63396332343139643839353033343562396131363035383665623964626366393939613637306361
62383237343962623662626332326238646233663865623932666134393836393461346633303237
64636231353732323434356662326230363936633861393965633438326236616561396165303365
63383436373139393331633264313062353839616131346338613336386662366362346136663234
32333534336161396562616664343666356233646435633633316465643161333862623062353933
30363261373065393937343039313662346163336530376166383738346261656438346565653239
62653237383437626361613037613039646562393261366633653837303461356562306562373239
61356634393361646330336332343932363334633637613339636637356338313031333263643538
63303962383664383565646530346634636463656437303262376366303035383962666230393963
36643462633730303564623261313531393336363830326363376135303436643531636465336532
61623333303832323964643038643237353164633633303636623233396639346332323737656631
37666331366239353339303636653437313665373837613566396665316165313138646261326262
62653365323538653566303434653031363966613839636661306130393133363932326166333739
33623932633138633035383363363962313932366634646263356631653836643932616632656163
63306334616261663933316165363736363232643536633561373636343131653633336436613531
39366234373836313166636239356137313166346133366332643430363437613331326265386536
65646461396435376265333262383061613931356261303938666334633836666137633962336636
36646535653235623638326264643464316533313031333665633338356133646363303931346431
39613438306663326630396664376238363761633136326135323564326361386164373639386136
37353966343838336538333231336263303438343339336531663932383131326166663932613236
31356530613938383364383262616338366635316636363061373832663563373536613062643939
62613532376630666134363564333430643532613361653138326330656235623231306435613233
32356635306135363335313431366139643335393634643738643135303835636138633736373932
39306463393538636165666439656231333066363632633364636266646663356535336237336530
31393436303437323531306232383262613661303430643237626337363835353731343862643863
31626561616136313835363433313165363762313038613132643330393465323362366636636538
30343331313037633262336332613361356130323136353864633432386432653534353837656665
62343765363935323964616632336339616364376130313463613739653732636234373334343539
37356236303463323163613038623166366464643531346536346136643631626665363262656130
64626334336138343062343738326132393866613531303436636436636262616237636333393464
38363962643236336335626130353833356536303235303930333636636332623230626534336436
62373037313261383261666433303635633834336133353231383532383864626536306337303966
36393736363030396337346132396463636565303737313065643233363732366661626264623632
37313535353032356531656635323366366563313932333564343962636430393862313231313333
37623231333834626535646639373536333031666661386163326339623835316632336639663533
61313733643530303065343137386564323335303937623835343862666630303233656438343163
37356537326131366131346433663635333734666630623530306232626233303562613231363733
34653330383334333366393239386135333732313734313266316361316630616530393038633863
36333363626165633264636162393339356162623130313162363064393065666437393564653831
63326336613265663664326337643333666332353961373061303536353563346166376535636362
66343233653265663564616331336263396334393534333664613533383566663437633466306566
36303363613238313933653739356639306263346539376131363132346337363965646333663230
31363962643634386663383634396163653761313639306663633864646265633464366130353037
31623631626330333663353935336434313333376465366463306233383066396163636233663739
32316663613365326661633235343838623564386134303832623164356362353833313631323961
64376362383536316537633138376138313266303738323866626365613963323531373736386534
64666231663935363262383536636665653463616465323661393331373539386332663131313034
63306230366262373332613638363434656261336236353739383539326233316130633064333162
38343864333638363933636234326664316338623136386436663038326234386433303635656530
37636137363934326561666663383362656430306132366161383765393632303263666437643535
65316438633435626434323135326262643263636437376232616463393663353431333034653536
66613139666365333062623763373737313935373763663534346536386636326131323532613762
30353066326635343432393435353737656465373639386366333863626334343664626138373838
61656665633761343735366236333261613132363965653866306233356133353333643933623463
63313533383036396461343138353935303637316133643166383335663631633436646332326365
66383961393034646633313364653765613434333561333638323237383165666163643162323364
36316534346361636264323866616439623062626462373361616138343261643732303638363262
30373162353039623463356136633262623039626532343464613066613635643062636232396165
64346263623564616165333631376466653539323761316165303233653839333138393436323836
30353466363639306662386165306666393137323264323461636239636232386536373039633136
35366436663362303065373431386530623666353666353630343337333030363036333365633762
35613061373530353264643163663064376563346262616138333938643961326664326638306665
32653037366563373861343961363836666436336332613063356466643335666266306531383736
64313063393365646466393366396166613835393933346461313434373164313432663432633432
37616439353963656165346165336261316535326639633363343131336565353338666461386662
31396531336666366131373664636130376538323062633238373238326637373633653864313762
35323264336438303634626237343332656362343736633538636166323834343064616333653164
61613766326236353761303733393862613166323465376561623731333832336336613038363063
37313665333237623539346237643530663763393263373963356265363831633233623439633132
30356664363933353064343433333338383762326632653338343039623662373262346564313130
63626239383166663330373961623265376162396537373561663632363933313835383762636639
30386434353131393062323663663662653966333532333938353036323833633138613435323133
62373631313234303434623366653531333139646632323065343137346231373666336139343566
64376266303931626564643632616665313933393732373235626363663235613561633765616462
61633335646332393439393534326435376638616462613261646636663062326130356437376238
33353064383537643536643238656437636365383563653934396132373761386666633232363133
65656631313232633839333330633735326433316436666233633132616332306361346361313134
38623966323066616663303663613136646562633061373765393663373738303666323736393565
32643439636230643139383562343565313265323739613134326465643435663936353233396331
37383862343666393766323132613262303530363731366231343961396135306332373066653931
35396462353964363365663234386437663238383431396564666434613237386238646338376334
36303463343762363365613965386566303461343435626437326562643736656431393632356337
61323431346635613637363665663233373932633362343862636261306161313637666363396435
39326564363061323861653763313862663834376631326565383763343832623163383661373762
31353233636431666130386338303263333039633436636561363939663432613735626630336236
31303339616439393130643961646433646433663234663738623662666162333036383665663230
36653665323636306132353032373435623639336364323937306637333138623638636434663161
62623064656166343562313466653062373361366530366639333861366261343235306536653732
39663366616666356335336439643262343463646232643933373631326530306165346530386631
34366665653833353364613339323539383034636230643537636237316539616665383332343330
38333661373135363430633631336166663866393834373238616263323934313530653465363261
34396463363665343063393632346363646137383833343730386337663035636137366434306231
35623737333962623235363563303165633766313330326330633138633830616539363133303765
39613566373732376633376638363532633833353737396434326666623331356161643033373533
34373538346262333664633438643339663766653862396666333664373036393838663662383263
61613639653063633230383536623165316166333534393866363533366363313161386339313034
61373636346331353032353664663339623736323031623438373331323962393564393866663363
64336662646561386537313464383236653839336432646566396363306235303166346164393763
39626465336539356364373266303866636365643633316139313036383033346433613332386638
66336535316233316638316434613466373639393831623333653831326262616231616566326137
31613236363236393039313265666532353736306238663036343434336237626539373333303430
63313462316161303666383863363439623433383862346232663466373636636335366364393630
63643639313733326165616364396463636237633035313738393333626635366538333563353565
65666238646530623337376232366138393832363530633865326333633564396461383666326638
30376233396631613536643565333866636265623366383336386131383661643835376566393031
37646664633638653837643135633831333662616264613434623930373334346232643965383533
65303766366434623236336538643761613131616134396366316435333636353837623239646234
36623730383264656131353463393631333862633433343437663438613738353133303030346635
32343039383333376132303063363530343539383431393865343834323430653934376330393632
39663133383466346562323863646233376664306662663331333262366331363130386332396638
39643061353532626637306265353231376266353665333031613734616539343064326136373833
34663638643239363132653965653733653836303838346433336161356262363533636566613239
63333234346561356665656530333461303838363230336538643061393566383764613134623966
30303465383636376164313066623863393737386335303036356632653761306533643737313437
36373038633330363935633137653665346166306634633161326662363739643363613366613636
38353638343465646635363164373066386261643963366161646536323566316539323532653434
34323965373264383335393265313834646436363338383237373634346437356266383463646663
32303436353166396130346432333962363365336663346131386366646132646234386135613537
31353138323635316130623663656634653861663430343137633434303563343831656530643934
65636235386231623430373734623534323839363639613566323231333536613833626336326335
39373232333764656666666264323431353762343137643031393436633533613663366631643764
31373433323131303230366263653064356539396462383464363039363735336363326164623363
39386263666366626538626163376466373463613366383266316633633565333363323734663334
33383965633061636437393935646166326263636265666163333431613036633066613861633165
32373163333430353234346262643933313138333262633530353361616564316664643336343865
39353665633434613939373838323636383662636262333836613932386366366363616131643337
63333762303737323062376166633531653065653332346236613766646163373936343164613735
65666163633033653634663931363738346134323835373132366165666665313338653233333064
38313139313265303838343162326238666433666432613038613465333032626536326264366238
30323239303538316463613238663163656430336531386138343661663537326364356135366239
65303830663631626638623131386532373435393136386365366431356232383933303665363439
64333730336565663036303166316461313439623263303862323334633361643866663932613633
37303765323331336333393831333935646134636263613632346661313134366434656637373134
66386236316633646436616639306130623361633662666336663337326533626436346462306536
61636135663038336461633530333335393231666163303737643030663235613938643162363166
33333338373934343634323030663265386339323965346566326237313965376139333631663432
62333932653532636632323730646434623730653366366337326235613631643634663437323864
33343361313462653065393439306431356561616432383761643038656534316330336563343739
62396335306636646535643036613731393463333033666236376630613930663334306332613766
35633864653233353863613034373434373032653035653364346466613431306632383563323234
34316663643632323962383831643662333632326632663065343830393131303937336231313435
62303737643664323762386438373631366161363833626665343236323765353131626434373237
31393437326266646633396134343535333434643532373264303438616536303435653832343836
30363566633264333533376262356234626561326663663932326265306139393163353632383534
66383335396639303239653439383233313266326137393731663761666564386135633934343763
37623434383935316634316333303830313935316166323161396332376265656530316566616566
64623732393938666333346336366538323436383136333161656463316337383832316530373531
37383335306536656230303065346630386633656334663432613362653462653039376533313831
65386431633234383237393235343236613538346333633839373165656663303735346238323535
30393132643330643735613433373666626630366339326661363935666336386333323831623930
36306635646536386561343038633938663866626462626239633062623039363163316133373330
38373038343333653139393264303735653362313063643630373563373638626332663934323861
38613936363636633863376535653365643732313135633736616435373930353136633337363263
65306230613964646136663235393161333163313234633261613965333531306238666137333430
35313233323032356662643931393164383765336361346239306435353035373339653364613962
66336632616133396431626265663634613434633834316538643434326565643461616432613266
32663032636537626564613761326239393033353666623136656435366266656133623332643639
38643431373430366239396463626338633038613634636362653865633561623934356130623465
34636139323932393931373538393033343061653232386164333137393837323630646166383231
62393366323663386265386232363135346164373839666638343235313433656336383766306637
37306230303030333633613335396462343162323063663733616230663138326366616533393762
62313162626639383166643636653165353263643335666161386433366539333530376138646237
36343132333463666432363065636333623561343135393730333134333161613763616232383832
32623365323435306436623836366663623566653330333461663263343964646164663666646330
39623533343664653364376233356261316365343265343134636432373264343230393135613763
31356238303263656261356237613139303836306166613234666266383966333037343862353466
38643731366537326331356334323931663863646362613831323063326266353434646539653130
39343865386231316130396636326231313463663435393135383333623135613434373062326664
66346461666333666337316565393634326630353331346362386334613564356561373539623030
62323638343936363735613436653466353037633864623163373161623837313462396231333637
64643036626135373364636339646637636231653666363765386533373066663132633161376433
39643730313534306337626161643265626634633666346539323662326533393738666437663033
32306365663231343938663832663363346432646531646332623966383862326662643463383936
65666631363237663734633733393234323337353738376633373036626331313663633734353762
35366239343339623632616632653865653239323831326566613630363463393233323933373863
61343131336236393164393563386539656536306333333137636461373966653266343861343631
66303439323964363365383466666633356335376665393239623861363838373032303036653438
38626239393035383438386639643137396665613531323864356162616435333236346530393166
62326434303838343331623664396664613962333262303435313966633133366466643966383166
36633866313830633532643934333935643661653833366663306538366161623634393665333464
31633161663562653031366465666232313434333635373435326330316234633132623436653163
32366334356233363265623438353430623131376637343636653237326334323930363239343765
37383630613630653939663462366538386161663833646138643734313332376434613366336239
36666363386464393663396263353862383932333962393362393638376564366330333538633733
33666363306634356334343230656231363534383734326331636165653164633232653935353731
31343633396236363936613138363266656562306364323738666539326563396639616364623538
66343336616165626436333134373336613463346334336432383331656535366439323332313765
33656231653939373362653062353438333232343266653566646361343132616234656661336432
36626137653330386633316332383036393834643461363563343831326266636462306639613232
62393931363431613738356630663636613139326465333666643533373739663763653266363537
36613333383035333933353038633437633435333061303463323161366634376261396463313961
62613536326665366534363761346231656566396332373866356138653731663762633733303831
65336561636333336533633036356638623039376261306632653038383138646164666635633130
33376161366364303138666139326164303966666636343436373633306134396663616231656638
62656163343264383939393964633332616162653861623334313865316331613733356133396164
38626438623430656538316161616538306636393762303966363534643661353037666561636362
36386466353632646638643831313665613862343431633561383837363433643630643136646234
63663538643465663536333265306139313839653338373134306562646537313135666437373364
31623236663164323235323661363534373763326261646365323435376665356162326635313339
64613731363039616166623930653839653865323036383331643864313137393136643631306262
32623666396536356435333862616461616365646333636366323633656338393464333035616136
66333737643037346630306366636338376133663964623165386136303863616134643163346565
61376339343661343962653532383431653662313534383435306165623936656331646131333165
30333233313261616261653439396464656132306137646535333639666463303464396530356435
64363137343335343961313665623135636564343061396666343765373865313535346130653462
32356638343862376335616232613964373535396230323738393334303435396264616236613763
61343435646130326464306466623161303730393830336536623865643635616462666436633833
65353936623335623431313863633138613566356134313966383635343731323039373566333030
31643139376261373436333437333563303034636663633563373335313163316332643839306261
39656330653334343231393937336666313539303863646638363539666634343538623432376635
61643161396632356462363331316664346231393266653035646565643434376332383836643932
39653933323065366330343039326565616539326336626539346466323136366431363734663731
31613534323661376364386464356135633235353435353532316563356639376431316431356235
61376266643334373561636336373535316166373538376165653637323661646233376439316465
39323465356436326334616465306432353665616631623566313638363962313066353636393033
62633133346438323735386563626564613938626363346561613138303537376330633066326237
33666231396333616562323238326334383932393439363134326362653532623432396635343235
62306338613664353336663933356436663430613935313437613332353363383435633434393935
36316161326435323235623961393535366534346366346439316131623834633066393162393363
39633265643536643962376130383038306139303633616665666166323038356232666566626665
39363539366335626564653536366462303535383337646437383064363837303232326638336639
36633031356134623864356435366434363763393036616236373437313735663964653136393561
30333732656363306238646461303065383836373333663766333534623233623863346431353036
65313661666236376631333832343138363735633035366435303636336131336435363463646332
63316461333533336637656435643333663062333464616562613465376337353361356165376134
62646561323866636265353865343931643237326439353738633832343837323466663731333834
38333632376435666663363665323862656162626563623938303135393432323531373865656431
61313737613064303033663633336161363366653735323461623734616663643766366632333761
35363836643964666438336263623536643536333264653933613961666634613438646233373733
65363035316631383733373934353830373365393034303032633062366466336334666266356365
34376435336639386139633136663031333331356462323961373239636539326662653363333139
32613037373630393464386437373338623833313638326136623564616333653436366635363633
63373735333435343863636235656439613034333539633861643365383938613764633566303464
31386132373635323264376436373637383364326361343838333034626462376432373539643137
34313865306135636262666537373465633564613465626438656133313537656235653262373836
30626264663332626161396439393636333965383763363739663239663861373530393233343630
33363161343435663561343862336262333132613537316664663937653062316133363436646531
33393736336434306132616130303131333335633166626634666266636436383939396634613664
34386665393933353131333061323366306430666661316164326665363664323630366165376465
36303365383130336631653166613365353264343461666232313964643236333761306131386364
37666434653133393435356663323637333138373262633731333735663633353736623738336462
36393965333336376664626238316335636463343165653235373334346462633863383266343336
38393837303162313736356462323432666161663565386133643531383833666537316232616565
62363439313230383162643336306466643836333032626337666133613032366636333162373536
65383836363435616435343737316331363232333838366533313166656133663232353232313837
32613838393463626632343836323966316131636433663865356366303331336231633864636262
61656466356432323931393831393436333963396138333733303630313133353461346535363930
61653637306636366261633032633935333966323164336436653564356631396430383135663738
62666536663666346338626430663439376631623863643665366636393736316432653835663938
65376132653661656235663364383630663262646138636438303933363830613231666261306666
39613731633765313163386237313636663632333263623734646133316364313061386630333862
34346662646139393434313432653236333134613430383939353136633462353830656264383862
36613764313036663431666363333731656338336238643036323363373732373137396166333762
32373835633261373338623031646562653664613232303865316631393562393631343265363734
61666462313334623938613032306131616135633266323763636533656534373138333336366636
31653831616437303637363364653330393336643865393438383834353636616130643834353330
66613162393435613566613838353136343634353061316666383832303633303865633531333665
66613032353939616639656463333137333234656263666233373532623463646466363662626630
31653039383534656239333339613832613233363037306465643437376130316337653262353030
31363761653932313061306663376661353138343735383337373634396131623233666264633365
34343936313739616536613531343437613963613163366636386661643631343963346632386532
31313338656236313432336662643835653935633063626432393963626436656463653231613536
66383462313737363436376438666232383635353662356532653030383537636661323262323833
32363761383035373330356137346663366364376237343535383231306538376139616235633463
66343632636565653363356563323831623030656134303733313535656164646439653966636366
30336530373733313163373030393930613030386531366565363439653738626262326533616264
32643964376435333638663131663730306436353664643835643132663865376232363862366566
37366130623933623761306437363135316339356635373565626132346338396436663931323662
35613433613739656530333862623533326237616633626438626163373137306539643366613863
63313230616434623065396630383363666433336538646637623961653138316235373432363164
39623436636336316430323661313335633963613736623862623663383837636363653833623866
30346332303338633538393035653939333562336262323865313931323534356137396337323263
64313464313664313234393866666534633538383031323564356432666233633363643539613034
37653436323438356135396239366530623333613034323762326366663437303961653038653566
31306332333331306233363663376661373635376662393337666365616563653132633662626138
32343863623433356161663966326633666539663361663562313834353736313831393039333037
37343564666531313836656162363235326566653561303330626664613461613039643964313331
34383536663938366330383030343836373263643034396634633338396333383237346531326339
63656233323139646165346633376266346630343039393534363233656466336264616632396362
61303830323536326630326236643231353838396662653737393261393030343834613236623864
64626434303739626463313838333734653963626639636433366236373563663462646139623933
34386663316230626662383266623230666565353365326565616635386366653664626134623561
33326630383663626361633761336533346239393435346637386566613632633931393537623138
38373235663833396164656432373936363434366564633032323335393162323962373939626537
65636263393965363863623663353739386564353964353965653231346233666536663032383935
64323262373062646436666337663239386262626237663132376531303139303433353762393730
39336433396433353262363137663231633032366637303139376234363332353931616338383264
31353966663961623832343237336630366632353765343632363032623663393061306532663639
61306231323236306436323435666534646633353739376138376335613333353638396139623936
32303837633539626264383163613361313239383066333562363636663939303166333665366638
62376230373635323932383265623838343762303734363235383233356465346430633338336134
35303064376239663162353738353763323734653539346439346435646561306635633039346562
37336631313561323533376563356234653465313235313734633530303234393131356261336338
31666666306266323332643462326266616663386464386132333435326561646531313937626439
65663562326639623133383030303032353038613436623765323436383337323165376139396130
39663430363330663834306132616231646438643038656332313234323831383235323933303635
63373064353434393366393139626431393838643239383730373365656235623039613530626134
34613764363834373066646262363031633630376331363435363137323834313063656135376164
33393433383937383762313331613934323031623339646631623430376162353734663933323830
31396130373938613236373737313931336332326333333039306330343033343164303438663464
36663233383263306664313837313037323033633430623037333536653065346264373132356261
39373032663636323439623062616330373135383965363366623630376136376232396136353032
37303363653535323835666561326463393934363831616133646130663933626333323236636437
62666236633039633737633531373534343535646666353835663237636230346365353862333065
39636234346665303864623439663136373937303136363339376137653566646566366538653262
39316363623966626232303765363737343835303332393633313263333836636239356432343330
38303038616135616531366264663634326465613164626531613361303839386233623861363738
39306637303738323231653231363335363535396664646662396366643764376266373331633262
35313366633033363731303839343766306335333831316334326334396430356431613536343835
31616535313337396566333930316537376432396439626563616264613037383833383437636439
32366236383637323231313130616333303164393064353239373664303636343266363039613530
33343632323263653834656562613231313734313234393232313665383831366339633435646564
32653863386439316435356164326138643732396635396235663762653362616665356632366237
30643039393939633061643063366532386366623038373064393538643565653339666536303232
33343462346532313937633236356532386634383561373335666535383035316261353263643639
31303061363239383131313639323830653732393635623339303336363231353734313262313331
39343366353137373034323933376566383165653234356461623561316264666130303566363837
39663462363863643164663362383632343833356639396465343262303733306337366236333861
31373933643036653961333235643065363064356365616231303739313762326536396434303738
31326666316537396566316161343964346364633239653937663635373133356164376634363635
34646634623963393335396239633661356132336433386163653361336366646538636661633765
32323432623738306335396234633563313666636638316637313639636261333331373933316461
32393339613138363765333166313935623131623164643933323935366439306338653663326238
61353661623462643630313238623432653338393663303763613366396238396437326337363833
32626133356439373865373038653934303933363430613163613031646537326236623539646339
61633530303236306132306238366635363134353837323966343462373263356165383836623664
39323234346538653261623038313535636431393262376130383863353866303263306138613565
31376661613436356665653335623266373461336433316235356261313633663737363961626634
64376637643165333666626561343137306562323935666632653439376664383461626331633162
37636363353864356564363739366334373633663036613962323030333133626131616363316630
32303135623934356231333036313163353666383731363337343061383563616164373339666131
65386530316639376263396438643233613430313964373563343363306338313036306437613930
35396334306263303739666232366261343333613536333634636631396636383838386431323436
31643036643332353563303037633964343832326164353236323939343763363134313262623165
39383030383261626133373062346332306634396137383638343339646130646362663735396238
39376633363666346435343766626632303463666661303637343831393864626234326364386635
38366539313331313463643237626239306666356465663131376361653830306239383933353364
36663435306338633933636161343533336130633065313761353733323165326437343332663962
38653631313538613334326234386434376561643433356336303837656236323335393235313435
63323536333461666161626434663630646333363634346133393161386237653831333336653137
39643137663731326630343962373837353665383832396164303037393634626436363238333637
31623866333161633934633932363563396262613238653765363038383765626430353866343036
63363335326462346266653134343031333463663332326134373234393362323161393937333939
37333263303262626463336637363363306264663532646533303738393335643431623438383535
37643632353661323063616166623739343333663061326566303531313362393333353262323438
36656663653433373937613539663738313831653433633636626132326633353561663234333565
39393735356561636438336165353438623231373333383432323933663063616336313533356435
38383765636339666330333866373264326436663136356532363435653465336130313730383735
38343039653730343632373430373437356163343761353535353037373033343132313630616265
66373338343366323937616162333937326131646630613137316162333361633964356364376362
61356665326264653036613832326663366566656231646338323730613439313036353136653338
32653664623232306265643238353834303336383034376533633361323538316236306565646466
37383638613337636566626131353363306133616336623832303337633366386361306132663464
65636566393431326433306262663932633065303563303136303338663966633466373861656564
31396336383635393464326531613631396230633261623636303563346332343065353438353537
37316666623364386137356638386635323861613331643835643639353332656662363163306433
34373134626466336566633162653761333736303565323430313736613439396634316430336261
36313839313137343732656461633766316432613661346631613834346263393535383262653966
65656366376436396264303830353130363533303263626537386530643166323666326534316634
30353463666334336338633062353739643434343438336138363435633161613037323738346563
39653130646462313331393061366332626263666266623261366137363337626530613136333539
66343639666461623230653936396230613137666264373036613334646136323963323039313231
39353131363235396234376537346539663235373862646263646463623033383837383834626661
31386236313762303732343139663763616265393034306638326431373736613837343636316437
64386139343239646337343263393933613734623239623633666332646463366261316232383633
38363964313563616331306235373363653162393830326639366434666463336336656635353461
64623537646633393536663739653439623564353064383334323166616435363532663362613532
62643431653764323739343631656264363862323630633539366464366165626464373337343937
32323938376461643165383630313832636530653562366232373661316132343237633364326437
64353466373232363966666631663137643563396564623033366133393733663538623834346361
39373238653434313335343263616565353939666536393865303734663464333535386161376432
36623333383164393535386232373263393032376234656639613231356230663339613236346434
39303161303531656332623630336562346164613834663430646432386236346364646337363365
64316666353762323666646461353837303963623465333063326362313834616365313335353233
33326464623435306231653263666261643335326262323261373030303133613036383834346634
33383664373932366534663034323366653566613366636535326435363336303765383261393334
35646366653838323832303434343933666662633134396136356432316136346461633539363636
31326435396366373565353730623834383437343139316266626664373064653664316639623031
32633362643966626166373937616561363366306535353762353463373733303939623462323134
63663936643566303864663465633066323463396233396266643963383262343732373231366635
39623138313430666536313031656631626431343034336438666464343037666133366364663437
62616334383730323937386530366564353136313464323631363730313930383131333263383039
66633737623738633233643838373934363030343065613362626634633565373565356433346665
37306333666233633833653135313734313638646461316439303461633832663835326330616534
64653635366266323532646462626438633536643662646631396363376263386433653666643036
66323163623164343232376561343239333037316465666662666233366162383839656665393135
37373230333762326362306132623433646361636135303862663636313033373765333037663363
63316135313338346635303038613236326232306261643032323730613065356539646163633833
35323961303461393535633632633233366538333261666237383438313365383063363361653736
32306438663263323737643464663966373933643433353638396533323564633739633165643665
64633233353166656466383637626462643463343462333332616631613364346334306435386164
35666632396663306166386364346661353764373435616332663030393535623064356135353061
37313638633530366339353362313434373731303331363164623737396438623435633635653537
66383831353731363061306636623565353037313764613130636565653236376335613864363862
62346166613734663131613663633234396532626438643035326333363166616634323432316334
39356362363161343564653765393339333930343433343861633633633032363436366533373461
64343036336664303834366165376166306137343732343665303765366465383834316263386561
63626234393462336132383461343732393665343262323732303135326130656561353238376634
34363534373366323633376262323036626537323939633561333836323736323032653862383963
34383564376237656638653561393862366264613034623265323163343265333762363834333234
64363965626363663265363062386137616263636461306466663663353231306532303064636538
38303730393931386261333634303534613865343231363338333836373636373737356265336364
31383033396532386335383265373735643765616136633964343266663431366133636662663235
39336138613063643766613037333864383766306565373265396133356635343066393462313963
31616436663366383134343236613265346363646137663732376234313135393864333762383934
34623139306433333535313365356537643264386561343134383738666163643262643232333465
33323662363032386235353631333238333265323161646438643732303562653435386133303438
32383434356531393566343839663165396131646132383033663431363230376330623463636439
38633966396162663838333632323063393762346530306266663166346635343166386238313137
31366262626232333431323437616466626538386666623333643566356665393238366161376163
63663338303065633238366661633666333839646231633038623636646265396566333630396362
38653265313637316438653365306634663436613233366134656261376630396163626530386131
66323934643637313230663139366363373839343533663337323065373238343761333563356131
34303061626239643366393632303161323762656364653532323136303936316364626538626130
62373331336261366636623034613836326637343838633135363138343965383838626362383962
61303032323035383866333130333238613139643333393961376564366266353235643135336363
38363663656433336463633437666262316237653637306331663563666438323361356433313238
61336437643666396535323566643565323039303738653632326530303261653332356537383563
33303232343236343362313161663363636662346265313639383265393664616335313435353439
33393432663137353339613035633833626534613130323236323764393062303836656162346337
61316264656234366262613738363730636336333862306532313730616635656536646463343363
61333539373564303634363136323236306639383833656339646236623062623234366463336261
61386434313065633466626339353466666437326536313633646333363833623339353930633065
36396662646231333132316435333964383339313635316139343963633133343036333336343063
64363661383633353938396539373332376236633964386133366362333161363461313739306631
65353138663433616664303533643635326564353737353133653838636464306265316533383232
62323862613666633562363936616362383163376438353963653930613961616666646263303939
32363630396164326564613263396530356437343836336630616437363466396339363330313731
62663034373733366337303838633762383430356564366333643364643165623761376237353834
65343466353662363737376266333564373839613663656636376161613734323066306331646561
65393365323537623963656663623766386130613262373639386265376136386465363634663938
34666336633263663864326261376334613734623764343563316539653066356166356432633435
61323164316361386630653636653337393866613462666637336630323161343139376261313164
63363137363963383961623633623835346266623832643363386330323134653864386338303238
66393135663662353238386136656632343933616263306266356434666435646165363063626431
61633534623734636331333637323332396563303763303239313236623831343162646638303865
61633765323135386564646132383732613937396534656333393961383563336337623163633538
38633262643237366363636130353339356636363835396263343765663238303361383832636435
31383833633134376561616663616361636263623366383365353238366336356233623233616531
66326339353439343764326566393035396162616162353233653835393534666362643532656265
36313038386135303364366165313636383537613736316162313965326638353236363338373061
64373061646439623436626430326661636338343639623935356636633936656430656461633432
65323635353030636466313035393866303032333339373262653933353930303463383132626234
38343766356234333939393731663162346430343766636665393862373030646636346631363062
36636165666135343762383436356363353134363731393566653365663466663966653665363864
39643865373534623331636333663466336131633461616162623561633534303963316263633836
30323639653439386335613935626131376133656265376365316433346336353636313664616263
36663637303330316532626564633530383236346336336335356636653231656432336239363638
66386163383539663032626434393264353330353332363939383032323165636236373231363437
31613833313336636664353561366131613231353464343737373039393465356631343062643338
31616533343066393466623036623230346538323638333038663164306465636439303864363565
33313064616431363636373039393433383433396161636336336232396130366339313132393164
39636534336164316663643364303165633732303131316664363139616339653263663161326366
66663236613438643666663334303366653631383639646362633564646334353637386236633737
38346439393564383564636164366630353462346635346230643135636134653432343861303764
30396634653037373162373463323862333364323465376464343436343533626231656338303733
30623864363234653631313033623937643133616137386633623361376631613038613837376462
37663065633732393236666433323132343636353935653062303637656165356639653735383639
61613933356335306165616531643135373831316362323138653532653633626362306365323636
33306236636433313930636162343462303663663366643766336436383464613531336136663363
32353330613733646531363336336565316461656631636636626666616432346534376465373861
38363031653031366563363664663334396163656662303965333033626366363531306134323635
30623662633331623939

View file

@ -1,14 +0,0 @@
---
################################
################################
## GitHub Enterprise Handlers ##
################################
################################
####################
# GHE config apply #
####################
- name: GHE Config Apply
ansible.builtin.command: ghe-config-apply
poll: 0
async: 300

View file

@ -1,88 +0,0 @@
---
- name: Wait for admin port to open
######################
# Set the tags block #
######################
tags:
- metrics
- github
- ghe_primary
- initialize
block:
- name: Wait for Admin port to come up (Port 8443)
## Doc: http://docs.ansible.com/ansible/latest/modules/wait_for_module.html
## Helpful Google: ansible wait_for
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 8443
delay: 5
timeout: 300
state: started
changed_when: false
#################################
# Wait for successful open port #
#################################
- name: Wait for http status 200
changed_when: false
ansible.builtin.uri:
url: "https://{{ ansible_host }}:8443"
validate_certs: "no"
register: http_result
# ignore_errors: true
until: http_result.status == 200
retries: 100
delay: 3
#######################################################
# Copy License file to GHE to decrypt file and upload #
#######################################################
# Copy of the file will allow for Ansible Vault to decrypt the file
# and place it on the new remote machine
- name: Copy collectd-settings.json File to GHE
become: true
ansible.builtin.template:
src: "collectd-settings.json.j2"
dest: /tmp/collectd-settings.json
owner: admin
group: admin
mode: 0644
########################################################
# Set up Admin password, License, and Initial Settings #
########################################################
- name: Setup Grafana
# yamllint disable
ansible.builtin.shell: curl --fail -Lk \
-X PUT "https://api_key:{{ github_admin_password }}@{{ ansible_host }}:8443/setup/api/settings" \
--data-urlencode "settings=`cat /tmp/collectd-settings.json`"
# yamllint enable
retries: 10
delay: 5
register: http_collectd_config_result
until: http_collectd_config_result.rc == 0
notify: ghe config apply
#####################################
# Edit forwarding.conf with metrics #
#####################################
- name: Copy forwarding.conf File to GHE
become: true
ansible.builtin.template:
force: true
src: "forwarding.conf.j2"
dest: /etc/collectd/conf.d/forwarding.conf
owner: root
group: root
mode: 0644
###########################################
# Restart Collectd service to take effect #
###########################################
- name: Restart Collectd service
become: true
ansible.builtin.service:
name: collectd
state: restarted

View file

@ -1,68 +0,0 @@
---
- name: GHE API Configuration
######################
# Set the tags block #
######################
tags:
- github
- ghe_primary
- initialize
block:
# ##################################
# # Run config to take in settings #
# ##################################
# - name: Run ghe-config-apply for Settings to Take Effect
# shell: "nohup ghe-config-apply </dev/null >/dev/null 2>&1 &"
# async: 45
# poll: 0
# args:
# executable: "/bin/bash"
##################################
# Run config to take in settings #
##################################
- name: Run Configure for Settings to Take Effect
ansible.builtin.uri:
url: "https://{{ ansible_host }}:8443/setup/api/configure"
method: POST
return_content: "yes"
user: "api_key"
password: "{{ github_admin_password }}"
force_basic_auth: "yes"
validate_certs: "no"
status_code: 202
#################################################################
# Wait for 'ghe-config-apply' to be completed before continuing #
#################################################################
- name: Ensure ghe-config-apply is completed
# https://docs.ansible.com/ansible/uri_module.html
# yamllint disable-line
# https://developer.github.com/enterprise/v3/enterprise-admin/management_console/#check-configuration-status
ansible.builtin.uri:
url: "https://{{ ansible_host }}:8443/setup/api/configcheck"
method: GET
return_content: "yes"
user: "api_key"
password: "{{ github_admin_password }}"
force_basic_auth: "yes"
validate_certs: "no"
register: configcheck
until: configcheck.status == 200 and configcheck.json.status == "success"
retries: 100
delay: 10
#####################################
# Remove the files from the machine #
#####################################
# Need to remove the license file and settings
# files that were copied to the ghe server
- name: Remove temp Files from GHE
become: true
ansible.builtin.file:
path: "{{ item }}"
state: absent
with_items:
- "/tmp/ghe-license.ghl"
- "/tmp/settings.json"
- "/tmp/ldap-settings.json"

View file

@ -1,33 +0,0 @@
---
- name: GHE Config apply
######################
# Set the tags block #
######################
tags:
- github
- ghe_primary
- initialize
block:
########################################
# Copy the script to the local machine #
########################################
- name: Copy the script to the GHE instance
become: true
ansible.builtin.template:
force: 'yes'
src: "ghe-config-apply.sh"
dest: /tmp/ghe-config-apply.sh
owner: admin
group: admin
mode: 0755
##################################
# Run config to take in settings #
##################################
- name: Run ghe-config-apply for Settings to Take Effect
ansible.builtin.shell: "nohup ./tmp/ghe-config-apply.sh </dev/null >/dev/null 2>&1 &"
async: 300
poll: 0
args:
executable: "/bin/bash"

View file

@ -1,88 +0,0 @@
---
- name: GHE Initial configuration
######################
# Set the tags block #
######################
tags:
- github
- ghe_primary
- initialize
block:
###############################
# Wait for admin port to open #
###############################
- name: Wait for Admin port to come up (Port 8443)
# yamllint disable-line
## Documentation: http://docs.ansible.com/ansible/latest/modules/wait_for_module.html
## Helpful Google: ansible wait_for
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 8443
delay: 5
timeout: 300
state: started
changed_when: false
#################################
# Wait for successful open port #
#################################
- name: Wait for http status 200
changed_when: false
ansible.builtin.uri:
url: "https://{{ ansible_host }}:8443"
validate_certs: "no"
register: http_result
# ignore_errors: true
until: http_result.status == 200
retries: 100
delay: 3
#######################################################
# Copy License file to GHE to decrypt file and upload #
#######################################################
# Copy of the file will allow for Ansible Vault to decrypt the file
# and place it on the new remote machine
- name: Copy License File to GHE
become: true
ansible.builtin.copy:
src: "{{ role_path }}/files/ghe-license.ghl"
dest: /tmp/ghe-license.ghl
owner: admin
group: admin
mode: 0600
#######################################################
# Copy License file to GHE to decrypt file and upload #
#######################################################
# Copy of the file will allow for Ansible Vault to decrypt the file
# and place it on the new remote machine
- name: Copy settings.json File to GHE
become: true
ansible.builtin.template:
src: "settings.json.j2"
dest: /tmp/settings.json
owner: admin
group: admin
mode: 0644
########################################################
# Set up Admin password, License, and Initial Settings #
########################################################
- name: Setup License, Admin Password, and Initial Settings
ansible.builtin.command: curl --fail -Lk \
-X POST "https://{{ ansible_host }}:8443/setup/api/start" \
-F license=@/tmp/ghe-license.ghl \
-F "password={{ github_admin_password }}" \
-F "settings=</tmp/settings.json"
retries: 10
delay: 2
register: http_initialconfig_result
until: http_initialconfig_result.rc == 0
###################################
# Set the GHE Admin Password fact #
###################################
- name: Set the GitHub Admin password fact
ansible.builtin.set_fact:
github_admin_password: "{{ github_admin_password }}"

View file

@ -1,31 +0,0 @@
---
- name: GHE LDAP configuration
######################
# Set the tags block #
######################
tags:
- openldap
block:
#######################################################
# Copy License file to GHE to decrypt file and upload #
#######################################################
# Copy of the file will allow for Ansible Vault to decrypt the file
# and place it on the new remote machine
- name: Copy ldap-settings.json File to GHE
become: true
ansible.builtin.template:
src: "ldap-settings.json.j2"
dest: /tmp/ldap-settings.json
owner: admin
group: admin
mode: 0644
#######################################
# Set up LDAP with ldap-settings.json #
#######################################
- name: Setup ldap with ldap-settings.json
ansible.builtin.shell: curl --fail -Lk -X PUT 'https://api_key:{{ github_admin_password }}@{{ ansible_host }}:8443/setup/api/settings' --data-urlencode "settings=`cat /tmp/ldap-settings.json`" # yamllint disable-line
retries: 10
delay: 2
register: http_ldapconfig_result
until: http_ldapconfig_result.rc == 0

View file

@ -1,34 +0,0 @@
---
- name: Configure the GHE Instance
tags:
- github
- ghe_primary
- initialize
block:
######################################################
# Need to run the tasks to stand up the GHE instance #
######################################################
# Configure the base system
- ansible.builtin.include_tasks: ghe-initial-configuration.yml
- name: Configure the GHE LDAP
tags:
- openldap
block:
############################################################
# Need to run the tasks to config LDAP on the GHE instance #
############################################################
# Configure the base system
- ansible.builtin.include_tasks: ghe-ldap-configuration.yml
- name: Configure the GHE Instance Block
tags:
- github
- ghe_primary
- initialize
block:
######################################################
# Need to run the tasks to stand up the GHE instance #
######################################################
# Configure the base system
- ansible.builtin.include_tasks: ghe-api-config-apply.yml

View file

@ -1,67 +0,0 @@
---
- name: Splunk settings
######################
# Set the tags block #
######################
tags:
- splunk
- github
- ghe_primary
- initialize
block:
###############################
# Wait for admin port to open #
###############################
- name: Wait for Admin port to come up (Port 8443)
## Doc: http://docs.ansible.com/ansible/latest/modules/wait_for_module.html
## Helpful Google: ansible wait_for
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 8443
delay: 5
timeout: 300
state: started
changed_when: false
#################################
# Wait for successful open port #
#################################
- name: Wait for http status 200
changed_when: false
ansible.builtin.uri:
url: "https://{{ ansible_host }}:8443"
validate_certs: "no"
register: http_result
# ignore_errors: true
until: http_result.status == 200
retries: 100
delay: 3
#######################################################
# Copy License file to GHE to decrypt file and upload #
#######################################################
# Copy of the file will allow for Ansible Vault to decrypt the file
# and place it on the new remote machine
- name: Copy splunk-settings.json File to GHE
become: true
ansible.builtin.template:
src: "splunk-settings.json.j2"
dest: /tmp/splunk-settings.json
owner: admin
group: admin
mode: 0644
########################################################
# Set up Admin password, License, and Initial Settings #
########################################################
- name: Setup Splunk
# yamllint disable
ansible.builtin.shell: curl --fail -Lk \
-X PUT "https://api_key:{{ github_admin_password }}@{{ ansible_host }}:8443/setup/api/settings" \
--data-urlencode "settings=`cat /tmp/splunk-settings.json`"
# yamllint enable
retries: 10
delay: 5
register: http_splunk_config_result
until: http_splunk_config_result.rc == 0
notify: ghe config apply

View file

@ -1,10 +0,0 @@
{
"collectd": {
"enabled": true,
"server": "{{ collectd_server }}",
"port": {{ collectd_port }},
"encryption": null,
"username": null,
"password": null
}
}

View file

@ -1,9 +0,0 @@
LoadPlugin network
<Plugin network>
<Server "{{ collectd_server }}" "{{ collectd_port }}">
ResolveInterval "300"
</Server>
</Plugin>

View file

@ -1,193 +0,0 @@
#!/usr/bin/env bash
################################################################################
# Script to run ghe-config-apply on the primary GHES instance
# and wait for any previous runs to complete
################################################################################
###########
# Globals #
###########
GHE_CONFIG_PID='/var/run/ghe-config.pid' # PID file when a config is running
GHE_APPLY_COMMAND='ghe-config-apply' # Command running when a config run
SLEEP_SECONDS=20 # Seconds to sleep before next check
PID_CHECK_LIMIT=15 # How many times to check the pid before moving on
PID_CHECK=0 # Count of times to check the pid
PROCESS_CHECK_LIMIT=15 # How many times to check the process before moving on
PROCESS_CHECK=0 # Count of times to check the process
################################################################################
########################### SUB ROUTINES BELOW #################################
################################################################################
################################################################################
#### Function CheckShellErrors #################################################
CheckShellErrors() {
COUNTER=$1
##############################
# Check the shell for errors #
##############################
if [ "${ERROR_CODE}" -ne 0 ]; then
error "Failed to sleep!"
error "[${SLEEP_CMD}]"
info "Will try to call apply as last effort..."
####################################
# Call config apply as last effort #
####################################
RunConfigApply
else
#####################
# Increment counter #
#####################
((COUNTER++))
##########################################
# Try to check for the pid/process again #
##########################################
$2
fi
return "$COUNTER"
}
################################################################################
#### Function CheckGHEPid ######################################################
CheckGHEPid() {
##################################
# Check to prevent infinite loop #
##################################
if [ ${PID_CHECK} -gt ${PID_CHECK_LIMIT} ]; then
# Over the limit, move on
info "We have checked the pid ${PID_CHECK} times, moving on..."
else
################################################
# Check to see if the PID is alive and running #
################################################
if [ ! -f "${GHE_CONFIG_PID}" ]; then
# File not found
info "We're good to move forward, no .pid file found at:[${GHE_CONFIG_PID}]"
else
# Found the pid running, need to sleep
info "Current PID found, sleeping ${SLEEP_SECONDS} seconds before next check..."
################
# Sleep it off #
################
SLEEP_CMD=$(sleep ${SLEEP_SECONDS} 2>&1)
#######################
# Load the error code #
#######################
ERROR_CODE=$?
PID_CHECK=CheckShellErrors "PID_CHECK" "CheckGHEPid"
fi
fi
}
################################################################################
#### Function CheckGHEProcess ##################################################
CheckGHEProcess() {
##################################
# Check to prevent infinite loop #
##################################
if [ ${PROCESS_CHECK} -gt ${PROCESS_CHECK_LIMIT} ]; then
# Over the limit, move on
info "We have checked the process ${PROCESS_CHECK} times, moving on..."
else
####################################################
# Check to see if the process is alive and running #
####################################################
CHECK_PROCESS_CMD=$(pgrep -f "${GHE_APPLY_COMMAND}" 2>&1)
#######################
# Load the error code #
#######################
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ ${ERROR_CODE} -ne 0 ]; then
# No process running on the system
info "Were good to move forward, no process like:[${GHE_APPLY_COMMAND}] running currently on the system"
else
# Found the process running, need to sleep
info "Current process alive:[${CHECK_PROCESS_CMD}], sleeping ${SLEEP_SECONDS} seconds before next check..."
################
# Sleep it off #
################
SLEEP_CMD=$(sleep ${SLEEP_SECONDS} 2>&1)
#######################
# Load the error code #
#######################
ERROR_CODE=$?
PROCESS_CHECK=CheckShellErrors "PROCESS_CHECK" "CheckGHEProcess"
fi
fi
}
################################################################################
#### Function RunConfigApply ###################################################
RunConfigApply() {
##########
# Header #
##########
info "Running ${GHE_APPLY_COMMAND} to the server..."
##############################################
# Run the command to apply changes to server #
##############################################
APPLY_CMD=$(ghe-config-apply 2>&1)
#######################
# Load the error code #
#######################
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ ${ERROR_CODE} -ne 0 ]; then
# Errors
error "Failed to run config apply command!"
fatal "[${APPLY_CMD}]"
else
# Success
info "Successfully ran ${F[C]}${GHE_APPLY_COMMAND}"
fi
}
################################################################################
################################## MAIN ########################################
################################################################################
######################
# Check for pid file #
######################
CheckGHEPid
#############################
# Check for running process #
#############################
CheckGHEProcess
####################
# Run config apply #
####################
RunConfigApply
###########################################
# We're going to run it again after a nap #
# to make sure there is no crazy actions #
###########################################
sleep 300s
######################
# Check for pid file #
######################
CheckGHEPid
#############################
# Check for running process #
#############################
CheckGHEProcess
####################
# Run config apply #
####################
RunConfigApply

View file

@ -1,35 +0,0 @@
{
"auth_mode": "ldap",
"ldap": {
"host": "{{ ldap_host }}",
"port": {{ ldap_port }},
"base": [
"{{ ldap_base_dn }}"
],
"uid": null,
"bind_dn": "{{ ldap_bind_dn }}",
"password": "{{ ldap_password }}",
"method": "{{ ldap_method }}",
"search_strategy": "detect",
"user_groups": [],
"admin_group": "{{ ldap_admin_group }}",
"virtual_attribute_enabled": false,
"recursive_group_search": false,
"posix_support": true,
"user_sync_emails": {{ ldap_user_sync_emails }},
"user_sync_keys": {{ ldap_user_sync_keys }},
"user_sync_gpg_keys": {{ ldap_user_sync_gpg_keys }},
"user_sync_interval": {{ ldap_user_sync_interval }},
"team_sync_interval": {{ ldap_team_sync_interval }},
"sync_enabled": {{ ldap_sync_enabled }},
"external_auth_token_required": false,
"verify_certificate": false,
"reconciliation.user": null,
"reconciliation.org": null,
"profile.uid": "{{ ldap_profile_uid }}",
"profile.name": "{{ ldap_profile_name }}",
"profile.mail": "{{ ldap_profile_mail }}",
"profile.key": {{ ldap_profile_key }},
"profile.gpg_key": {{ ldap_profile_gpg_key }}
}
}

View file

@ -1,112 +0,0 @@
{
"enterprise": {
"private_mode": {{ core_private_mode }},
"public_pages": {{ core_public_pages }},
"subdomain_isolation": {{ core_subdomain_isolation }},
"signup_enabled": {{ core_signup_enabled }},
"identicons_host": "dotcom",
"http_proxy": {{ core_http_proxy }},
"http_noproxy": {{ core_http_noproxy }},
"auth_mode": "default",
"builtin_auth_fallback": {{ core_builtin_auth_fallback }},
"expire_sessions": {{ core_expire_sessions }},
"avatar": null
},
"cas": {
"url": {{ cas_url }}
},
"saml": {
"sso_url": {{ saml_sso_url }},
"certificate": {{ saml_certificate }},
"certificate_path": "{{ saml_certificate_path }}",
"issuer": {{ saml_issuer }},
"name_id_format": "{{ saml_name_id_format }}",
"idp_initiated_sso": {{ saml_idp_initiated_sso }},
"disable_admin_demote": {{ saml_disable_admin_demote }},
"signature_method": "{{ saml_signature_method }}",
"digest_method": "{{ saml_digest_method }}",
"username_attribute": {{ saml_username_attribute }},
"full_name_attribute": "{{ saml_full_name_attribute }}",
"emails_attribute": "{{ saml_emails_attribute }}",
"ssh_keys_attribute": "{{ saml_ssh_keys_attribute }}",
"gpg_keys_attribute": "{{ saml_gpg_keys_attribute }}"
},
"github_oauth": null,
"smtp": {
"enabled": {{ smtp_enabled }},
"address": {{ smtp_address }},
"authentication": {{ smtp_authentication }},
"port": {{ smtp_port }},
"domain": {{ smtp_domain }},
"username": {{ smtp_username }},
"user_name": {{ smtp_user_name }},
"password": {{ smtp_password }},
"support_address": "{{ smtp_support_address }}",
"support_address_type": "{{ smtp_support_address_type }}",
"noreply_address": "{{ smtp_noreply_address }}",
"discard_to_noreply_address": {{ smtp_discard_to_noreply_address }}
},
"ntp": {
"primary_server": "{{ ntp_primary_server }}",
"secondary_server": "{{ ntp_secondary_server }}"
},
"timezone": null,
"snmp": {
"enabled": {{ snmp_enabled }},
"version": {{ snmp_version }},
"community": "{{ snmp_community }}",
"users": [
]
},
"syslog": {
"enabled": {{ syslog_enabled }},
"server": "{{ syslog_server }}",
"protocol_name": "{{ syslog_protocol_name }}",
"tls_enabled": {{ syslog_tls_enabled }},
"cert": {{ syslog_cert }}
},
"assets": null,
"pages": {
"enabled": {{ pages_enabled }}
},
"collectd": {
"enabled": {{ collectd_enabled }},
"server": "{{ collectd_server }}",
"port": {{ collectd_port }},
"encryption": {{ collectd_encryption }},
"username": {{ collectd_username }},
"password": {{ collectd_password }}
},
"mapping": {
"enabled": {{ mapping_enabled }},
"tileserver": {{ mapping_tileserver }},
"token": {{ mapping_token }}
},
"load_balancer": {
"http_forward": {{ loadbalancer_http_forward }},
"proxy_protocol": {{ loadbalancer_proxy_protocol }}
},
"abuse_rate_limiting": {
"enabled": {{ abuse_rate_limiting_enabled }},
"requests_per_minute": {{ abuse_rate_limiting_requests_per_minute }},
"cpu_millis_per_minute": {{ abuse_rate_limiting_cpu_millis_per_minute }},
"search_cpu_millis_per_minute": {{ abuse_rate_limiting_search_cpu_millis_per_minute }}
},
"api_rate_limiting": {
"enabled": {{ api_rate_limiting_enabled }},
"unauthenticated_rate_limit": {{ api_rate_limiting_unauthenticated_rate_limit }},
"default_rate_limit": {{ api_rate_limiting_default_rate_limit }},
"search_unauthenticated_rate_limit": {{ api_rate_limiting_search_unauthenticated_rate_limit }},
"search_default_rate_limit": {{ api_rate_limiting_search_default_rate_limit }},
"lfs_unauthenticated_rate_limit": {{ api_rate_limiting_lfs_unauthenticated_rate_limit }},
"lfs_default_rate_limit": {{ api_rate_limiting_lfs_default_rate_limit }},
"graphql_unauthenticated_rate_limit": {{ api_rate_limiting_graphql_unauthenticated_rate_limit }},
"graphql_default_rate_limit": {{ api_rate_limiting_graphql_default_rate_limit }}
},
"governor": {
"quotas_enabled": {{ governor_quotas_enabled }},
"limit_user": {{ governor_limit_user }},
"limit_network": {{ governor_limit_network }}
}
}

View file

@ -1,9 +0,0 @@
{
"syslog": {
"enabled": true,
"server": "{{ splunk_host }}:{{ splunk_port }}",
"protocol_name": "udp",
"tls_enabled": false,
"cert": null
}
}

View file

@ -1,3 +1,6 @@
// disable ClassNameSameAsFilename because super-linter follows a specific
// file name for tests.
// groovylint-disable-next-line ClassNameSameAsFilename
class Example {
static void main(String[] args) {
File file = new File("E:/Example.txt")

View file

@ -0,0 +1 @@
package com.example;

View file

@ -17,4 +17,5 @@ ls -la
### Walk away
We're all done **here**.
- [Link Action](https://github.com)