Skip to content

Commit

Permalink
test action (#2)
Browse files Browse the repository at this point in the history
* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action

* test action
  • Loading branch information
Noahnc authored Oct 29, 2023
1 parent 84ee9d2 commit 16625a9
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 38 deletions.
29 changes: 27 additions & 2 deletions .github/workflows/action_integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:

jobs:
integration-test:
env:
report_json_file: InfraPatch_Statistics.json

name: "Run GitHub Action integration test"
runs-on: ubuntu-latest
steps:
Expand All @@ -21,14 +24,36 @@ jobs:
- name: Run in report only mode
uses: ./
with:
push_changes: false
report_only: true

- name: Run in update mode
id: update
uses: ./
with:
push_changes: false
report_only: false
target_branch_name: "feat/infrapatch_test_${{ github.run_number }}"

- name: Check update result
shell: pwsh
run: |
$report = Get-Content $env:report_json_file -Raw | ConvertFrom-Json
if ( -not $report.total_resources -gt 0 ) {
throw "Failed to get resources"
}
if ( -not ( $report.resources_patched -gt 3 ) ) {
throw "No resources should be patched"
}
if ( $report.errors -gt 0 ) {
throw "Errors have been detected"
}
- name: Delete created branch$
if: always()
uses: dawidd6/action-delete-branch@v3
with:
github_token: ${{github.token}}
branches: ${{ steps.update.outputs.target_branch }}
soft_fail: true



Expand Down
38 changes: 25 additions & 13 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ inputs:
description: "Name of the branch where changes will be pushed to. Defaults to feature/infrapatch-bot"
required: true
default: "feature/infrapatch-bot"
repository_name:
description: "Name of the repository to run the action in. Defaults to the current repository"
required: false
default: ${{ github.repository }}
default_registry_domain:
description: "Default registry domain to use for modules and providers without explicit registry domain set. Defaults to registry.terraform.io"
required: false
Expand Down Expand Up @@ -33,16 +37,27 @@ inputs:
description: "Working directory to run the command in. Defaults to the root of the repository"
required: false
default: ${{ github.workspace }}
outputs:
target_branch:
description: "Name of the branch where changes will be pushed to"
value: ${{ inputs.target_branch_name }}

runs:
using: composite
steps:
- name: Extract branch name
id: head_branch
id: branch
shell: bash
run: |
head_branch="origin/${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
echo "Detected head branch: $head_branch"
echo "branch=$head_branch" >> $GITHUB_OUTPUT
head_branch_origin="origin/${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
head_branch="${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
target_branch="${{ inputs.target_branch_name }}"
target_branch_origin="origin/${{ inputs.target_branch_name }}"
echo "Using head branch $head_branch and target branch $target_branch"
echo "head=$head_branch" >> $GITHUB_OUTPUT
echo "head_origin=$head_branch_origin" >> $GITHUB_OUTPUT
echo "target=$target_branch" >> $GITHUB_OUTPUT
echo "target_origin=$target_branch_origin" >> $GITHUB_OUTPUT
- name: Install Python
uses: actions/setup-python@v4
Expand Down Expand Up @@ -78,15 +93,15 @@ runs:
shell: bash
run: |
git fetch origin
git checkout -b "${{ inputs.target_branch_name }}" "origin/${{ inputs.target_branch_name }}"
git checkout -b "${{ steps.branch.outputs.target }}" "${{ steps.branch.outputs.target_origin }}"
- name: Rebase target branch
if: ${{ steps.create_branch.outputs.created == 'false' }}
working-directory: ${{ inputs.working_directory }}
shell: bash
run: |
echo "Rebasing ${{ inputs.target_branch_name }} on ${{ steps.head_branch.outputs.branch }}"
git rebase -Xtheirs ${{ steps.head_branch.outputs.branch }}
echo "Rebasing ${{ steps.branch.outputs.target }} on ${{ steps.branch.outputs.head_origin }}"
git rebase -Xtheirs ${{ steps.branch.outputs.head_origin }}
- name: Run InfraPatch Action
shell: bash
Expand All @@ -103,13 +118,10 @@ runs:
arguments+=("--registry-secrets-string" "\"${{ inputs.registry_secrets }}\"")
fi
arguments+=("--github-token" "${{ inputs.github_token }}")
arguments+=("--head-branch" "${{ steps.branch.outputs.head }}")
arguments+=("--target-branch" "${{ steps.branch.outputs.target }}")
arguments+=("--repository-name" "${{ inputs.repository_name }}")
arguments+=("--working-directory" "${{ inputs.working_directory }}")
arguments+=("--default-registry-domain" "${{ inputs.default_registry_domain }}")
python -m "$module" "${arguments[@]}"
- name: Push changes
if: ${{ inputs.report_only == 'false' }}
working-directory: ${{ inputs.working_directory }}
shell: bash
run: |
git push
40 changes: 37 additions & 3 deletions infrapatch/action/__main__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import json
import subprocess
from pathlib import Path
import logging as log
import click
import pygit2
from github import Auth, Github
from github.PullRequest import PullRequest

from infrapatch.core.composition import build_main_handler
from infrapatch.core.log_helper import catch_exception, setup_logging
Expand All @@ -14,10 +17,13 @@
@click.option("--default-registry-domain")
@click.option("--registry-secrets-string", default=None)
@click.option("--github-token")
@click.option("--target-branch")
@click.option("--head-branch")
@click.option("--repository-name")
@click.option("--report-only", is_flag=True)
@click.option("--working-directory")
@catch_exception(handle=Exception)
def main(debug: bool, default_registry_domain: str, registry_secrets_string: str, github_token: str, report_only: bool,
def main(debug: bool, default_registry_domain: str, registry_secrets_string: str, github_token: str, target_branch: str, head_branch: str, repository_name: str, report_only: bool,
working_directory: str):
setup_logging(debug)
log.debug(f"Running infrapatch with the following parameters: "
Expand Down Expand Up @@ -45,7 +51,35 @@ def main(debug: bool, default_registry_domain: str, registry_secrets_string: str
return

main_handler.update_resources(upgradable_resources, True, working_directory, True)
main_handler.print_resource_table(upgradable_resources)
main_handler.dump_statistics(upgradable_resources, save_as_json_file=True)

push_changes(target_branch, working_directory)

create_pr(github_token, head_branch, repository_name, target_branch)


def push_changes(target_branch, working_directory):
command = ["git", "push", "-f", "-u", "origin", target_branch]
log.debug(f"Executing command: {' '.join(command)}")
try:
result = subprocess.run(command, capture_output=True, text=True, cwd=working_directory.absolute().as_posix())
except Exception as e:
raise Exception(f"Error pushing to remote: {e}")
if result.returncode != 0:
log.error(f"Stdout: {result.stdout}")
raise Exception(f"Error pushing to remote: {result.stderr}")


def create_pr(github_token, head_branch, repository_name, target_branch) -> PullRequest:
token = Auth.Token(github_token)
github = Github(auth=token)
repo = github.get_repo(repository_name)
pull = repo.get_pulls(state='open', sort='created', base=head_branch, head=target_branch)
if pull.totalCount != 0:
log.info(f"Pull request found from '{target_branch}' to '{head_branch}'")
return pull[0]
log.info(f"No pull request found from '{target_branch}' to '{head_branch}'. Creating a new one.")
return repo.create_pull(title=f"InfraPatch Module and Provider Update", body=f"InfraPatch Module and Provider Update", base=head_branch, head=target_branch)


def get_credentials_from_string(credentials_string: str) -> dict:
Expand Down
11 changes: 5 additions & 6 deletions infrapatch/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from infrapatch.core.utils.hcl_handler import HclHandler
from infrapatch.core.utils.registry_handler import RegistryHandler

main_handler = None
main_handler: MainHandler = None


@click.group(invoke_without_command=True)
Expand Down Expand Up @@ -48,15 +48,14 @@ def report(project_root: str, only_upgradable: bool, dump_json_statistics: bool)


@main.command()
@click.option("project_root", "--project-root", default=None,
help="Root directory of the project. If not specified, the current working directory is used. If commit-changes is set, this has to be the root of a git repository.")
@click.option("project_root", "--project-root", default=None, help="Root directory of the project. If not specified, the current working directory is used.")
@click.option("--confirm", is_flag=True, help="Apply changes without confirmation.")
@click.option("--dump-json-statistics", is_flag=True, help="Creates a json file containing statistics about the updated resources in the cwd.")
@click.option("--commit-changes", is_flag=True, help="Commits the changes to a git repository.")
@catch_exception(handle=Exception)
def update(project_root: str, confirm: bool, dump_json_statistics: bool, commit_changes: bool):
def update(project_root: str, confirm: bool, dump_json_statistics: bool):
"""Finds all modules and providers in the project_root and updates them to the newest version."""
if project_root is None: project_root = Path.cwd()
global main_handler
resources = main_handler.get_all_terraform_resources(Path(project_root))
main_handler.update_resources(resources, confirm, Path(project_root), commit_changes)
main_handler.update_resources(resources, confirm, Path(project_root))
main_handler.dump_statistics(resources, dump_json_statistics)
28 changes: 16 additions & 12 deletions infrapatch/core/composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path

import click
import rich
from git import Repo
from rich import progress
from rich.console import Console
Expand All @@ -23,13 +24,14 @@ def build_main_handler(default_registry_domain: str, credentials_file_path: str
if credentials_dict is None:
credentials_dict = get_registry_credentials(hcl_handler, credentials_file_path)
registry_handler = RegistryHandler(default_registry_domain, credentials_dict)
return MainHandler(hcl_handler, registry_handler)
return MainHandler(hcl_handler, registry_handler, Console(width=cs.CLI_WIDTH))


class MainHandler:
def __init__(self, hcl_handler: HclHandler, registry_handler: RegistryHandler):
def __init__(self, hcl_handler: HclHandler, registry_handler: RegistryHandler, console: Console):
self.hcl_handler = hcl_handler
self.registry_handler = registry_handler
self._console = console

def get_all_terraform_resources(self, project_root: Path) -> list[VersionedTerraformResource]:
log.info(f"Searching for .tf files in {project_root.absolute().as_posix()} ...")
Expand Down Expand Up @@ -87,8 +89,8 @@ def update_resources(self, resources: list[VersionedTerraformResource], confirm:
if repo.bare:
raise Exception("Working directory is not a git repository.")
log.info(f"Committing changes to git branch '{repo.active_branch.name}'.")
self.print_resource_table(resources, True)
if not confirm:
self.print_resource_table(resources, True)
if not click.confirm("Do you want to apply the changes?"):
print("Aborting...")
return []
Expand All @@ -101,28 +103,30 @@ def update_resources(self, resources: list[VersionedTerraformResource], confirm:
continue
if commit_changes:
repo.index.add([resource.source_file.absolute().as_posix()])
repo.index.commit(f"Updated {resource.resource_name} '{resource.name}' from version '{resource.current_version}' to '{resource.newest_version}'.")
repo.index.commit(f"Bump {resource.resource_name} '{resource.name}' from version '{resource.current_version}' to '{resource.newest_version}'.")
resource.set_patched()
return upgradable_resources

def _compose_resource_table(self, resources: list[VersionedTerraformResource], title: str):
table = Table(show_header=True,
title=title,
width=cs.CLI_WIDTH
expand=True
)
table.add_column("Name")
table.add_column("Current Version")
table.add_column("Newest Version")
table.add_column("Name", overflow="fold")
table.add_column("Source", overflow="fold")
table.add_column("Current")
table.add_column("Newest")
table.add_column("Upgradeable")
for resource in resources:
name = resource.identifier if isinstance(resource, TerraformProvider) else resource.name
table.add_row(
resource.name,
resource.source,
resource.current_version,
resource.newest_version,
str(not resource.installed_version_equal_or_newer_than_new_version())
)
console = Console()
console.print(table)
self._console.print(table)

def dump_statistics(self, resources, save_as_json_file: bool = False):
providers = [resource for resource in resources if isinstance(resource, TerraformProvider)]
Expand All @@ -144,7 +148,7 @@ def dump_statistics(self, resources, save_as_json_file: bool = False):
f.write(json.dumps(statistics))
table = Table(show_header=True,
title="Statistics",
width=cs.CLI_WIDTH
expand=True
)
table.add_column("Total Resources")
table.add_column("Resources Pending Update")
Expand All @@ -160,4 +164,4 @@ def dump_statistics(self, resources, save_as_json_file: bool = False):
str(statistics["modules_count"]),
str(statistics["providers_count"])
)
Console().print(table)
self._console.print(table)
2 changes: 1 addition & 1 deletion infrapatch/core/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Width of the cli interface
CLI_WIDTH = 130
CLI_WIDTH = 160

# Name of this App. Used all over the place in the cli
APP_NAME = "InfraPatch"
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pygohcl~=1.0.7
GitPython~=3.1.40
setuptools~=65.5.1
pygit2~=1.13.1
semantic-version~=2.10.0
semantic-version~=2.10.0
PyGithub~=2.1.1

0 comments on commit 16625a9

Please sign in to comment.