Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Community merge conflicts #113

Merged
merged 100 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
5414045
fix: create admin api key
yanksyoon Mar 16, 2023
33421a3
fix: revert to discourse from charmhub
yanksyoon Mar 16, 2023
a13becc
fix: typo
yanksyoon Mar 16, 2023
50f6381
fix: user & api key creation flow
yanksyoon Mar 17, 2023
9da601f
fix: upgrade discourse charm
yanksyoon Mar 19, 2023
e8bbc16
add function that retrieves the file contents
jdkandersson Mar 21, 2023
af7fbc7
add tests for retrieving content of a file
jdkandersson Mar 21, 2023
7f1e328
fix linting issues
jdkandersson Mar 21, 2023
d2ef605
remove unnecessary None alternative
jdkandersson Mar 21, 2023
40fdaf3
make repository client available to reconcile
jdkandersson Mar 21, 2023
fb6c853
add content from default branch to content change
jdkandersson Mar 21, 2023
115089b
fix: remove unlist parameter(user level api failure)
yanksyoon Mar 21, 2023
4af70d7
fix: update assert to pass returned content
yanksyoon Mar 21, 2023
5b1c9cc
fix: set hostname for successful redirect
yanksyoon Mar 21, 2023
944a45d
fix: static test dependency update to bandit w/ toml
yanksyoon Mar 21, 2023
8317844
fix: lint fixes
yanksyoon Mar 21, 2023
cf35ca6
test: wait for idle for longer
yanksyoon Mar 21, 2023
ed501be
test: give enough timeout for asset compile
yanksyoon Mar 21, 2023
b340f36
fix: deploy and wait for idle before getting status
yanksyoon Mar 21, 2023
cf43316
debug
yanksyoon Mar 21, 2023
0b868e8
fix: parse raw content
yanksyoon Mar 21, 2023
d850a2a
fix: lint fixes
yanksyoon Mar 21, 2023
2f4501d
fix: wait for idle not active status
yanksyoon Mar 22, 2023
88c7010
fix: content in paragraph tag
yanksyoon Mar 22, 2023
83db749
fix: backwards compatibility fix for e2e
yanksyoon Mar 22, 2023
eb65c39
fix: infinte wait fix
yanksyoon Mar 22, 2023
7f7d40f
add merge conflict module
jdkandersson Mar 22, 2023
2815790
add tests for content module
jdkandersson Mar 22, 2023
0a13c92
fix: set config after relations
yanksyoon Mar 22, 2023
4eafb6f
fix: reorder deploy flow
yanksyoon Mar 22, 2023
a9cbcf5
fix: wait for ip
yanksyoon Mar 22, 2023
b0e6ebe
fix: revert
yanksyoon Mar 22, 2023
368855f
chore: revert back to main operator workflow
yanksyoon Mar 22, 2023
45cec2b
chore: pin juju version & move to dev-requirements.txt
yanksyoon Mar 22, 2023
12c794e
chore: remove pre_run
yanksyoon Mar 22, 2023
43e3c65
fix linting issues
jdkandersson Mar 23, 2023
e7e4e9b
add module that checks actions
jdkandersson Mar 23, 2023
63faa56
refactor
jdkandersson Mar 23, 2023
acc8f7b
add check for any content conflicts
jdkandersson Mar 23, 2023
35d0157
add reconcile test with merge conflicts
jdkandersson Mar 23, 2023
a3cf054
add content merging
jdkandersson Mar 23, 2023
bc564a7
separate action tests into multiple modules
jdkandersson Mar 23, 2023
2f9fe75
fix linting issues
jdkandersson Mar 23, 2023
2e77eff
chore: add timeouts to requests
yanksyoon Mar 23, 2023
fddb8a0
test: separate out response parsing
yanksyoon Mar 23, 2023
3376403
chore: revert content assertions
yanksyoon Mar 23, 2023
c7ec6a7
fix: doc imperative mood fix
yanksyoon Mar 23, 2023
4d76466
test: fixturize admin API headers
yanksyoon Mar 23, 2023
5d29487
test: consistency fixes
yanksyoon Mar 23, 2023
41afb91
chore: remove unnecessary fstring
yanksyoon Mar 23, 2023
f33a012
fix: fixture reference
yanksyoon Mar 24, 2023
22398c6
merge fix/ci
jdkandersson Mar 24, 2023
06bbb10
add github token to e2e tests
jdkandersson Mar 24, 2023
fc9f657
move requirements to requirements.txt files
jdkandersson Mar 24, 2023
2148cef
add support for the case where the file was not found on the branch
jdkandersson Mar 24, 2023
651a160
add tests for no base
jdkandersson Mar 24, 2023
323c76a
add support for retrieving the file from a particular branch
jdkandersson Mar 24, 2023
5af706c
add base branch input
jdkandersson Mar 24, 2023
86b92d3
add tests for that file is retrieved from the correct branch
jdkandersson Mar 24, 2023
3afc02c
fix linting issues
jdkandersson Mar 24, 2023
233fc11
to trigger CI
jdkandersson Mar 24, 2023
c8a5793
merge main
jdkandersson Mar 24, 2023
15d0734
fix linting issues
jdkandersson Mar 28, 2023
c893551
fix wording issues
jdkandersson Mar 28, 2023
b5cd499
add integration test for merge conflict
jdkandersson Mar 28, 2023
dee0079
update docs
jdkandersson Mar 28, 2023
7224454
fix security issue
jdkandersson Mar 28, 2023
d9db83a
rename conflict so that it doesn't get caught by reconcile mark
jdkandersson Mar 29, 2023
4d4389f
aggregate clients into a tuple
jdkandersson Mar 29, 2023
3bd73f8
fix linting issues
jdkandersson Mar 29, 2023
4cdc71f
update attributes
jdkandersson Mar 29, 2023
c52b540
change to use constants
jdkandersson Mar 29, 2023
dc9507c
correct docs
jdkandersson Mar 30, 2023
e57a981
add more granular exception handling
jdkandersson Mar 30, 2023
de5774a
fix linting issue
jdkandersson Mar 30, 2023
5474bab
add update e2e test
jdkandersson Mar 30, 2023
4e0af57
remove spaces
jdkandersson Mar 30, 2023
e5aa0ac
change to append extra content
jdkandersson Mar 30, 2023
adbde17
show errors with deleting branch
jdkandersson Mar 30, 2023
b41441d
move the update content before branch creation
jdkandersson Mar 30, 2023
52c4c59
fix incorrect repo name
jdkandersson Mar 30, 2023
589f897
correct expected result
jdkandersson Mar 30, 2023
e1f2879
add branch argument where it was missing
jdkandersson Mar 30, 2023
b9f59c8
reenable all tests
jdkandersson Mar 30, 2023
39fb77a
change logic to be more maintainable
jdkandersson Mar 31, 2023
11ea738
move writing GitGHub output to separate module
jdkandersson Mar 31, 2023
eec8dd2
add docs for checking for conflicts
jdkandersson Mar 31, 2023
7ad1e78
correct grammar
jdkandersson Mar 31, 2023
6902a91
remove version pin for pytest-operator
jdkandersson Mar 31, 2023
277c536
remove unnecessary new lines
jdkandersson Mar 31, 2023
779a9cc
change to split the how and execution logic
jdkandersson Mar 31, 2023
8fc9d68
fix linting issue
jdkandersson Mar 31, 2023
06a44b4
switch back to Python 3.10 for now for test execution
jdkandersson Mar 31, 2023
a6a6b62
correct docs and log cleanup failures
jdkandersson Apr 3, 2023
a64bad2
remove unnecessary single quotes
jdkandersson Apr 4, 2023
4dd0908
add back exception that was removed
jdkandersson Apr 4, 2023
139d8f3
fix type
jdkandersson Apr 4, 2023
be4da3a
clarify variable name
jdkandersson Apr 4, 2023
a48401e
remove unnecessary del
jdkandersson Apr 4, 2023
c76d5f2
remove unnecessary comment
jdkandersson Apr 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion .github/workflows/e2e_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:

jobs:
e2e-tests-reconcile:
permissions: write-all
runs-on: ubuntu-22.04
steps:
# Each job has to have this configuration because secrets can be passed through the output of
Expand Down Expand Up @@ -56,6 +57,7 @@ jobs:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
dry_run: true
- name: Show pages
run: echo '${{ steps.e2e-test-draft.outputs.urls_with_actions }}'
Expand All @@ -71,6 +73,7 @@ jobs:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Show pages
run: echo '${{ steps.e2e-test-create.outputs.urls_with_actions }}'
- name: Check create
Expand All @@ -80,6 +83,28 @@ jobs:
run: |
echo "docs: ${{ steps.e2e-test-create.outputs.index_url }}" >> metadata.yaml
cat metadata.yaml
- name: Prepare for update test
id: e2e-test-prepare-update
run: |
# Update the contents of one of the files, do it first to get around content conflicts
echo -n more content >> docs/doc.md
GITHUB_TOKEN='${{ secrets.GITHUB_TOKEN }}'
REPO='${{ github.repository }}'
PYTHONPATH=$(pwd) python3 prepare_check_cleanup/reconcile.py --action prepare-update --action-kwargs "{\"github_token\": \"$GITHUB_TOKEN\", \"repo\": \"$REPO\", \"filename\": \"docs/doc.md\"}" '${{ steps.e2e-test-create.outputs.urls_with_actions }}' '${{ steps.configuration.outputs.discourse }}'
yanksyoon marked this conversation as resolved.
Show resolved Hide resolved
- name: Update self test
id: e2e-test-update
uses: ./
with:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
base_branch: ${{ steps.e2e-test-prepare-update.outputs.update_branch }}
- name: Show pages
run: echo '${{ steps.e2e-test-update.outputs.urls_with_actions }}'
- name: Check update
run: |
PYTHONPATH=$(pwd) python3 prepare_check_cleanup/reconcile.py --action check-update --action-kwargs '{"expected_url_results": ["success", "success", "success"]}' '${{ steps.e2e-test-create.outputs.urls_with_actions }}' '${{ steps.configuration.outputs.discourse }}'
- name: Delete the alternate doc with delete_topics disabled
run: rm docs/alternate_doc.md
- name: Delete topics disabled self test
Expand All @@ -90,6 +115,8 @@ jobs:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
base_branch: ${{ steps.e2e-test-prepare-update.outputs.update_branch }}
- name: Show pages
run: echo '${{ steps.e2e-test-delete-topics.outputs.urls_with_actions }}'
- name: Check delete topics disabled
Expand All @@ -104,6 +131,8 @@ jobs:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
base_branch: ${{ steps.e2e-test-prepare-update.outputs.update_branch }}
- name: Show pages
run: echo '${{ steps.e2e-test-delete.outputs.urls_with_actions }}'
- name: Check delete topics enabled
Expand All @@ -112,7 +141,9 @@ jobs:
- name: Clean up
if: always()
run: |
PYTHONPATH=$(pwd) python3 prepare_check_cleanup/reconcile.py --action cleanup '${{ steps.e2e-test-create.outputs.urls_with_actions }}' '${{ steps.configuration.outputs.discourse }}'
GITHUB_TOKEN='${{ secrets.GITHUB_TOKEN }}'
REPO='${{ github.repository }}'
PYTHONPATH=$(pwd) python3 prepare_check_cleanup/reconcile.py --action cleanup --action-kwargs "{\"github_token\": \"$GITHUB_TOKEN\", \"repo\": \"$REPO\"}" '${{ steps.e2e-test-create.outputs.urls_with_actions }}' '${{ steps.configuration.outputs.discourse }}'
e2e-tests-migration:
permissions: write-all
runs-on: ubuntu-22.04
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ jobs:
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@main
secrets: inherit
with:
modules: '["discourse", "reconcile", "migrate"]'
modules: '["discourse", "reconcile", "conflict", "migrate"]'
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ jobs:
- name: Check for any code improvements
run: |
PYTHON_FILES=$(find . -name '*.py')
pyupgrade --py310-plus $PYTHON_FILES
pyupgrade --py311-plus $PYTHON_FILES
refurb $PYTHON_FILES
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ charmhub.
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Show index page
run: echo '${{ steps.publishDocumentation.outputs.index_url }}'
```
Expand Down Expand Up @@ -101,12 +102,12 @@ charmhub.
github_token: ${{ secrets.GITHUB_TOKEN }}
```

a branch name with `upload-charm-docs/migrate` will be created and a pull
request named `[upload-charm-docs] Migrate charm docs` will be created
towards the working branch the workflow was triggered with.
In order to ensure that the branches can be created successfully, please
make sure that there are no existing branches clashing with the name above.
Please note that `dry_run` parameter has no effect on migrate mode.
a branch name with `upload-charm-docs/migrate` will be created and a pull
request named `[upload-charm-docs] Migrate charm docs` will be created
targeting the default branch of the repository. In order to ensure that the
branches can be created successfully, please make sure that there are no
existing branches clashing with the name above. Please note that the
`dry_run` input has no effect on migrate mode.

The action will now compare the discourse topics with the files and directories
under the `docs` directory and make any changes based on differences.
Expand All @@ -117,3 +118,19 @@ Additional recommended steps:
publish a new version of the charm and documentation.
* Add the action in dry run mode on publishes to `edge` to see what changes to
the documentation will be made once you publish to `stable`.

## Discourse Documentation Edits

To ensure that contributions to the documentation on discourse are not
overridden, the action compares the content that was last pushed to discourse
with the current documentation on discourse and any proposed changes. If there
are changes both on discourse and in the repository, the action will attempt to
merge the content using essentially `git merge`. If that fails, the action will
prompt you to resolve those conflicts by editing the documentation on discourse
and on the repository. Be sure to explain the reasoning for the changes on
discourse.

Note that `git merge` will not make any changes on your branch. The content that
was last pushed to discourse is determined by getting the content from a given
file from the default branch of the repository. A different branch can be
configured using the `base_branch` input.
6 changes: 6 additions & 0 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ inputs:
Required if running in migration mode.
required: false
type: string
base_branch:
arturo-seijas marked this conversation as resolved.
Show resolved Hide resolved
description: |
The name of the branch that contains the documentation after it has been uploaded to
discourse. Defaults to the default branch of the repository.
required: false
type: string
outputs:
urls_with_actions:
description: |
Expand Down
4 changes: 4 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
ops
pytest-operator
factory_boy>=3.2,<3.3
pytest-asyncio>=0.21,<0.22
pytest>=7.2,<7.3
juju==3.0.4
2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def _parse_env_vars() -> types_.UserInputs:
delete_topics = os.getenv("INPUT_DELETE_TOPICS") == "true"
dry_run = os.getenv("INPUT_DRY_RUN") == "true"
github_access_token = os.getenv("INPUT_GITHUB_TOKEN")
base_branch = os.getenv("INPUT_BASE_BRANCH")

return types_.UserInputs(
discourse=types_.UserInputsDiscourse(
Expand All @@ -47,6 +48,7 @@ def _parse_env_vars() -> types_.UserInputs:
delete_pages=delete_topics,
dry_run=dry_run,
github_access_token=github_access_token,
base_branch=base_branch,
)


Expand Down
40 changes: 21 additions & 19 deletions prepare_check_cleanup/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import argparse
import json
import logging
import os
import sys
from contextlib import suppress
from enum import Enum
Expand All @@ -17,16 +16,16 @@
from github.PullRequest import PullRequest
from github.Repository import Repository

from prepare_check_cleanup import exit_
from prepare_check_cleanup import exit_, output
from src.constants import (
DOCUMENTATION_FOLDER_NAME,
DOCUMENTATION_INDEX_FILENAME,
NAVIGATION_TABLE_START,
)
from src.discourse import create_discourse
from src.exceptions import DiscourseError
from src.index import DOCUMENTATION_FOLDER_NAME, DOCUMENTATION_INDEX_FILENAME
from src.pull_request import (
ACTIONS_PULL_REQUEST_TITLE,
DEFAULT_BRANCH_NAME,
create_repository_client,
)
from src.reconcile import NAVIGATION_TABLE_START
from src.pull_request import DEFAULT_BRANCH_NAME
from src.repository import ACTIONS_PULL_REQUEST_TITLE, create_repository_client


class Action(str, Enum):
Expand Down Expand Up @@ -78,8 +77,7 @@ def main() -> None:
case Action.CHECK_PULL_REQUEST.value:
exit_.with_result(check_pull_request(**action_kwargs))
case Action.CLEANUP.value:
cleanup(**action_kwargs)
sys.exit(0)
exit_.with_result(cleanup(**action_kwargs))
case _:
raise NotImplementedError(f"{args.action} has not been implemented")

Expand Down Expand Up @@ -110,14 +108,8 @@ def prepare(index_filename: str, page_filename: str, discourse_config: dict[str,

topics = {"index": index_url, "page": page_url}

github_output = os.getenv("GITHUB_OUTPUT")
assert github_output, (
"the GITHUB_OUTPUT environment variable is empty or defined, "
"is this running in a GitHub workflow?"
)
output_file = Path(github_output)
topics_output = json.dumps(topics, separators=(",", ":")).replace('"', '\\"')
output_file.write_text(f"topics={topics_output}\nindex_url={index_url}\n", encoding="utf-8")
output.write(f"topics={topics_output}\nindex_url={index_url}\n")


def _create_repository_client(github_access_token: str) -> Repository:
Expand Down Expand Up @@ -258,21 +250,27 @@ def check_pull_request(github_access_token: str) -> bool:

def cleanup(
topics: dict[str, str], github_access_token: str, discourse_config: dict[str, str]
) -> None:
) -> bool:
"""Clean up testing artifacts on GitHub and Discourse.
Args:
topics: The discourse topics created for the migration.
github_access_token: The secret required for interactions with GitHub.
discourse_config: Details required to communicate with discourse.
Returns:
Whether the cleanup succeeded.
"""
result = True

# Delete discourse topics
discourse = create_discourse(**discourse_config)
try:
for topic_url in topics.values():
discourse.delete_topic(url=topic_url)
except DiscourseError as exc:
logging.exception("cleanup failed for discourse, %s", exc)
result = False

github_repo = _create_repository_client(github_access_token=github_access_token)
# Delete the migration PR
Expand All @@ -282,13 +280,17 @@ def cleanup(
migration_pull_request.edit(state="closed")
except GithubException as exc:
logging.exception("cleanup failed for migration pull request, %s", exc)
result = False
# Delete the migration branch
try:
migration_branch = _get_migration_branch(github_repo=github_repo)
if migration_branch:
migration_branch.delete()
except GithubException as exc:
logging.exception("cleanup failed for migration branch, %s", exc)
result = False

return result


if __name__ == "__main__":
Expand Down
22 changes: 22 additions & 0 deletions prepare_check_cleanup/output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.

"""Functions that support writing output."""

import os
from pathlib import Path


def write(text: str) -> None:
"""Write text to the GitHub output file.
Args:
text: The content to write to the GitHub output.
"""
github_output = os.getenv("GITHUB_OUTPUT")
assert github_output, (
"the GITHUB_OUTPUT environment variable is empty or defined, "
"is this running in a GitHub workflow?"
)
output_file = Path(github_output)
output_file.write_text(text, encoding="utf-8")
Loading