[Bug] Adjust build-release CLI and fix links when generating security docs (#3434)

* removed historical argument; added setup string; fixed links

* fixing flake errors

* added types for command arguments

* adjusted get_release_diff to append strings for release tags

* set fetch-depth to 0 for integrations checkout in workflow

* changed the name of the workflow

* removed TODOs

* adjusted release docs workflow to remove prefix for release tags

* adjusted URL replacement only if pointed to docs site

* added elastic website to regex pattern

* add docstrings; adjusted regex; add note for stopgap

* added a note about the regex pattern for elastic URLs

(cherry picked from commit 06b97ec79b)
This commit is contained in:
Terrance DeJesus
2024-02-12 10:08:06 -05:00
committed by github-actions[bot]
parent 934edfd618
commit 00fe4c8283
5 changed files with 45 additions and 25 deletions
+22 -19
View File
@@ -86,15 +86,13 @@ def dev_group():
@click.option('--update-version-lock', '-u', is_flag=True,
help='Save version.lock.json file with updated rule versions in the package')
@click.option('--generate-navigator', is_flag=True, help='Generate ATT&CK navigator files')
@click.option('--add-historical', type=str, required=True, default="yes",
help='Generate historical package-registry files')
@click.option('--generate-docs', is_flag=True, default=False, help='Generate markdown documentation')
@click.option('--update-message', type=str, help='Update message for new package')
def build_release(config_file, update_version_lock: bool, generate_navigator: bool, add_historical: str,
def build_release(config_file, update_version_lock: bool, generate_navigator: bool, generate_docs: str,
update_message: str, release=None, verbose=True):
"""Assemble all the rules into Kibana-ready release files."""
config = load_dump(config_file)['package']
registry_data = config['registry_data']
add_historical = True if add_historical == "yes" else False
if generate_navigator:
config['generate_navigator'] = True
@@ -105,26 +103,27 @@ def build_release(config_file, update_version_lock: bool, generate_navigator: bo
if verbose:
click.echo(f'[+] Building package {config.get("name")}')
package = Package.from_config(config, verbose=verbose, historical=add_historical)
package = Package.from_config(config, verbose=verbose)
if update_version_lock:
default_version_lock.manage_versions(package.rules, save_changes=True, verbose=verbose)
package.save(verbose=verbose)
if add_historical:
previous_pkg_version = find_latest_integration_version("security_detection_engine", "ga",
registry_data['conditions']['kibana.version'].strip("^"))
sde = SecurityDetectionEngine()
historical_rules = sde.load_integration_assets(previous_pkg_version)
historical_rules = sde.transform_legacy_assets(historical_rules)
previous_pkg_version = find_latest_integration_version("security_detection_engine", "ga",
registry_data['conditions']['kibana.version'].strip("^"))
sde = SecurityDetectionEngine()
historical_rules = sde.load_integration_assets(previous_pkg_version)
historical_rules = sde.transform_legacy_assets(historical_rules)
package.add_historical_rules(historical_rules, registry_data['version'])
click.echo(f'[+] Adding historical rules from {previous_pkg_version} package')
# NOTE: stopgap solution until security doc migration
if generate_docs:
click.echo(f'[+] Generating security docs for {registry_data["version"]} package')
docs = IntegrationSecurityDocsMDX(registry_data['version'], Path(f'releases/{config["name"]}-docs'),
True, historical_rules, package, note=update_message)
docs.generate()
click.echo(f'[+] Adding historical rules from {previous_pkg_version} package')
package.add_historical_rules(historical_rules, registry_data['version'])
if verbose:
package.get_package_hash(verbose=verbose)
click.echo(f'- {len(package.rules)} rules included')
@@ -136,14 +135,14 @@ def get_release_diff(pre: str, post: str, remote: Optional[str] = 'origin'
) -> (Dict[str, TOMLRule], Dict[str, TOMLRule], Dict[str, DeprecatedRule]):
"""Build documents from two git tags for an integration package."""
pre_rules = RuleCollection()
pre_rules.load_git_tag(pre, remote, skip_query_validation=True)
pre_rules.load_git_tag(f'integration-v{pre}', remote, skip_query_validation=True)
if pre_rules.errors:
click.echo(f'error loading {len(pre_rules.errors)} rule(s) from: {pre}, skipping:')
click.echo(' - ' + '\n - '.join([str(p) for p in pre_rules.errors]))
post_rules = RuleCollection()
post_rules.load_git_tag(post, remote, skip_query_validation=True)
post_rules.load_git_tag(f'integration-v{post}', remote, skip_query_validation=True)
if post_rules.errors:
click.echo(f'error loading {len(post_rules.errors)} rule(s) from: {post}, skipping:')
@@ -155,12 +154,12 @@ def get_release_diff(pre: str, post: str, remote: Optional[str] = 'origin'
@dev_group.command('build-integration-docs')
@click.argument('registry-version')
@click.option('--pre', required=True, help='Tag for pre-existing rules')
@click.option('--post', required=True, help='Tag for rules post updates')
@click.option('--pre', required=True, type=str, help='Tag for pre-existing rules')
@click.option('--post', required=True, type=str, help='Tag for rules post updates')
@click.option('--directory', '-d', type=Path, required=True, help='Output directory to save docs to')
@click.option('--force', '-f', is_flag=True, help='Bypass the confirmation prompt')
@click.option('--remote', '-r', default='origin', help='Override the remote from "origin"')
@click.option('--update-message', default='Rule Updates.', help='Update message for new package')
@click.option('--update-message', default='Rule Updates.', type=str, help='Update message for new package')
@click.pass_context
def build_integration_docs(ctx: click.Context, registry_version: str, pre: str, post: str,
directory: Path, force: bool, update_message: str,
@@ -170,6 +169,10 @@ def build_integration_docs(ctx: click.Context, registry_version: str, pre: str,
if not click.confirm(f'This will refresh tags and may overwrite local tags for: {pre} and {post}. Continue?'):
ctx.exit(1)
assert Version.parse(pre) < Version.parse(post), f'pre: {pre} is not less than post: {post}'
assert Version.parse(pre), f'pre: {pre} is not a valid semver'
assert Version.parse(post), f'post: {post} is not a valid semver'
rules_changes = get_release_diff(pre, post, remote)
docs = IntegrationSecurityDocs(registry_version, directory, True, *rules_changes, update_message=update_message)
package_dir = docs.generate()