Skip to content

Commit

Permalink
feat: adds initial feature for git commits and remote pushes
Browse files Browse the repository at this point in the history
Signed-off-by: Jennifer Power <barnabei.jennifer@gmail.com>
  • Loading branch information
jpower432 committed Jun 21, 2023
1 parent a296e0b commit d9638d0
Show file tree
Hide file tree
Showing 13 changed files with 517 additions and 25 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length=100
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ lint:
@poetry run flake8
.PHONY: lint

format:
@poetry run isort --profile=black --lines-after-imports=2 $(TESTS) $(PYMODULE)
@poetry run black $(TESTS) $(PYMODULE)
.PHONY: format

test:
@poetry run pytest --cov --cov-config=pyproject.toml --cov-report=xml
.PHONY: test
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ trestle-bot assists users in leveraging [Compliance-Trestle](https://github.com/

In addition to trestle-bot, this repo contains the trestle-bot GitHub Action that can optionally be used to host the tresle-bot service within GitHub Actions.

> WARNING: This project is under active development.
## Usage

trestle-bot supports the following commands:
Expand All @@ -13,4 +15,23 @@ Converts repo defined markdown formatted OSCAL content to JSON.


### `/help`
Displays help information for trestle-bot.
Displays help information for trestle-bot.

## Contributing

### Format and Styling

```
make format
make lint
```

### Running tests
```
make test
```

### Run with poetry
```
poetry run trestle-bot
```
39 changes: 38 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
name: "trestle-bot"
author: "Red Hat Product Security"
description: "A workflow automation manager for OSCAL formatted compliance content"
outputs:

inputs:
commit_message:
description: Commit message
required: false
default: "chore: sync automatic updates"
branch:
description: Git branch name, where changes should be pushed too. Required if Action is used on the `pull_request` event
required: false
default: ${{ github.head_ref }}
file_pattern:
description: File pattern used for `git add`. For example `src/*.js`
required: false
default: '.'
repository:
description: Local file path to the git repository. Defaults to the current directory (`.`)
required: false
default: '.'
commit_user_name:
description: Name used for the commit user
required: false
default: github-actions[bot]
commit_user_email:
description: Email address used for the commit user
required: false
default: 41898282+github-actions[bot]@users.noreply.github.com
commit_author_name:
description: Named used for the commit author. Defaults to the username of whoever triggered this workflow run.
required: false
default: ${{ github.actor }}
commit_author_email:
description: Email address used for the commit author. Defaults to the email of whoever triggered this workflow run.
required: false
default: ${{ github.actor }}@users.noreply.github.com

runs:
using: "docker"
image: "REPLACE_ME"

branding:
icon: "check"
color: "green"
41 changes: 40 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file added py.typed
Empty file.
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ readme = 'README.md'

repository = 'https://github.com/RedHatProductSecurity/trestle-bot'

[tool.poetry.scripts]
trestle-bot = "trestlebot.cli:run"

[tool.poetry.dependencies]
python = '^3.8.1'
gitpython = "^3.1.31"

[tool.poetry.group.dev.dependencies]
flake8 = "^6.0.0"
Expand Down
169 changes: 169 additions & 0 deletions tests/test_bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/python

# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Test for top-level Trestle Bot logic."""

import os
import shutil
import tempfile

from git import Repo

import trestlebot.bot as bot


def repo_setup(repo_path: str) -> Repo:
repo = Repo.init(repo_path)
repo.config_writer().set_value("user", "name", "Test User").release()
repo.config_writer().set_value("user", "email", "test@example.com").release()
return repo


def create_tmp_directory():
tmp_dir = tempfile.mkdtemp()
print(f"Temporary directory created: {tmp_dir}")
return tmp_dir


def clean(repo_path: str, repo: Repo):
# Clean up the temporary Git repository
repo.close()
shutil.rmtree(repo_path)


def test_stage_files():
repo_path = create_tmp_directory()
repo = repo_setup(repo_path)

# Create initial commit
file1_path = os.path.join(repo_path, "file1.txt")
with open(file1_path, "w") as f:
f.write("Test file 1 content initial")
repo.index.add(file1_path)
repo.index.commit("my test")

# Create test files
with open(file1_path, "w") as f:
f.write("Test file 1 content")
with open(os.path.join(repo_path, "file2.txt"), "w") as f:
f.write("Test file 2 content")

# Stage the files
bot._stage_files(repo, ["*.txt"])

# Verify that files are staged
staged_files = [item.a_path for item in repo.index.diff(repo.head.commit)]

assert len(staged_files) == 2
assert "file1.txt" in staged_files
assert "file2.txt" in staged_files

clean(repo_path, repo)


def test_local_commit():
repo_path = create_tmp_directory()
repo = repo_setup(repo_path)

# Create a test file
test_file_path = os.path.join(repo_path, "test.txt")
with open(test_file_path, "w") as f:
f.write("Test content")

repo.index.add(test_file_path)

# Commit the test file
bot._local_commit(
repo,
commit_user="Test User",
commit_email="test@example.com",
commit_message="Test commit message",
)

# Verify that the commit is made
commit = next(repo.iter_commits())
assert commit.message.strip() == "Test commit message"
assert commit.author.name == "Test User"
assert commit.author.email == "test@example.com"

# Verify that the file is tracked by the commit
assert os.path.basename(test_file_path) in commit.stats.files

clean(repo_path, repo)


def test_local_commit_with_committer():
repo_path = create_tmp_directory()
repo = repo_setup(repo_path)

# Create a test file
test_file_path = os.path.join(repo_path, "test.txt")
with open(test_file_path, "w") as f:
f.write("Test content")

repo.index.add(test_file_path)

# Commit the test file
bot._local_commit(
repo,
commit_user="Test Commit User",
commit_email="test-committer@example.com",
commit_message="Test commit message",
)

# Verify that the commit is made
commit = next(repo.iter_commits())
assert commit.message.strip() == "Test commit message"
assert commit.author.name == "Test Commit User"
assert commit.author.email == "test-committer@example.com"

# Verify that the file is tracked by the commit
assert os.path.basename(test_file_path) in commit.stats.files

clean(repo_path, repo)


def test_local_commit_with_author():
repo_path = create_tmp_directory()
repo = repo_setup(repo_path)

# Create a test file
test_file_path = os.path.join(repo_path, "test.txt")
with open(test_file_path, "w") as f:
f.write("Test content")

repo.index.add(test_file_path)

# Commit the test file
bot._local_commit(
repo,
commit_user="Test User",
commit_email="test@example.com",
commit_message="Test commit message",
author_name="The Author",
author_email="author@test.com",
)

# Verify that the commit is made
commit = next(repo.iter_commits())
assert commit.message.strip() == "Test commit message"
assert commit.author.name == "The Author"
assert commit.author.email == "author@test.com"

# Verify that the file is tracked by the commit
assert os.path.basename(test_file_path) in commit.stats.files

clean(repo_path, repo)
5 changes: 0 additions & 5 deletions tests/test_foo.py

This file was deleted.

26 changes: 26 additions & 0 deletions trestlebot/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/python

# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import trestlebot.cli


def init() -> None:
"""Initialize trestlebot"""
if __name__ == "__main__":
trestlebot.cli.run()


init()
Loading

0 comments on commit d9638d0

Please sign in to comment.