Merge pull request 'Skip the metadata sync successfully when no GitHub mirror exists' (#28) from skip-sync-without-github-mirror into main
Reviewed-on: #28
This commit was merged in pull request #28.
This commit is contained in:
@@ -176,17 +176,18 @@ jobs:
|
|||||||
)
|
)
|
||||||
targets.append(tuple(path_parts))
|
targets.append(tuple(path_parts))
|
||||||
|
|
||||||
|
if not targets:
|
||||||
|
return None
|
||||||
if len(targets) != 1:
|
if len(targets) != 1:
|
||||||
raise WorkflowError(
|
raise WorkflowError(
|
||||||
"configuration",
|
"configuration",
|
||||||
"Expected exactly one GitHub push mirror for this repository; "
|
"Expected at most one GitHub push mirror for this repository; "
|
||||||
f"found {len(targets)}.",
|
f"found {len(targets)}.",
|
||||||
)
|
)
|
||||||
return targets[0]
|
return targets[0]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
github_token = parse_github_token(os.environ.get("GITHUB_CREDENTIALS"))
|
|
||||||
gitea_token = parse_gitea_token(os.environ.get("GITEA_CREDENTIALS"))
|
gitea_token = parse_gitea_token(os.environ.get("GITEA_CREDENTIALS"))
|
||||||
source_owner, source_repo = split_repository(
|
source_owner, source_repo = split_repository(
|
||||||
os.environ.get("SOURCE_REPOSITORY")
|
os.environ.get("SOURCE_REPOSITORY")
|
||||||
@@ -210,7 +211,16 @@ jobs:
|
|||||||
)
|
)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
github_owner, github_repo = find_github_targets(mirrors)
|
target = find_github_targets(mirrors)
|
||||||
|
if target is None:
|
||||||
|
print(
|
||||||
|
"No GitHub push mirror configured for "
|
||||||
|
f"{source_owner}/{source_repo}; nothing to sync."
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
github_token = parse_github_token(os.environ.get("GITHUB_CREDENTIALS"))
|
||||||
|
github_owner, github_repo = target
|
||||||
github_api_url = (
|
github_api_url = (
|
||||||
"https://api.github.com/repos/"
|
"https://api.github.com/repos/"
|
||||||
f"{urllib.parse.quote(github_owner, safe='')}/"
|
f"{urllib.parse.quote(github_owner, safe='')}/"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ It currently contains the Gitea workflow [`sync-github-metadata.yml`](.gitea/sco
|
|||||||
## 📋 Requirements
|
## 📋 Requirements
|
||||||
|
|
||||||
- A Gitea instance with Actions enabled and a runner providing `ubuntu-latest` with `python3`
|
- A Gitea instance with Actions enabled and a runner providing `ubuntu-latest` with `python3`
|
||||||
- A configured GitHub push mirror on the Gitea repository (exactly one)
|
- A configured GitHub push mirror on the Gitea repository (at most one; repositories without a mirror are skipped successfully)
|
||||||
- Repository secrets:
|
- Repository secrets:
|
||||||
- `TOKEN_FOR_GITEA`: Gitea API token (plain string, or JSON with `GITEA_TOKEN`)
|
- `TOKEN_FOR_GITEA`: Gitea API token (plain string, or JSON with `GITEA_TOKEN`)
|
||||||
- `CREDENTIALS_FOR_GITHUB`: JSON object containing `GITHUB_PAT`, a GitHub personal access token allowed to edit the mirror repository
|
- `CREDENTIALS_FOR_GITHUB`: JSON object containing `GITHUB_PAT`, a GitHub personal access token allowed to edit the mirror repository
|
||||||
@@ -111,6 +111,8 @@ Gitea --> Workflow: Push mirror response
|
|||||||
|
|
||||||
alt mirrors is not a list
|
alt mirrors is not a list
|
||||||
Workflow --> Trigger: Log a warning and succeed\n(GitHub metadata not synced)
|
Workflow --> Trigger: Log a warning and succeed\n(GitHub metadata not synced)
|
||||||
|
else mirrors is a list with no GitHub mirror
|
||||||
|
Workflow --> Trigger: Log that there is nothing to sync and succeed
|
||||||
else mirrors is a list
|
else mirrors is a list
|
||||||
Workflow -> Workflow: Find GitHub owner and repo from remote_address
|
Workflow -> Workflow: Find GitHub owner and repo from remote_address
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
## Version History
|
## Version History
|
||||||
| Date | Status | Author | Reviewer | Change | Commit |
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 2026-10-03 | Rejected | Jens Tirsvad Nielsen | S01 | Initial version | [4de5438] |
|
| 2026-10-03 | Deprecated | Jens Tirsvad Nielsen | S01 | Added S05 to assumptions, risks and stakeholders | [4de5438] |
|
||||||
| 2026-10-03 | Accepted | Jens Tirsvad Nielsen | S01 | Added S05 to assumptions, risks and stakeholders | [4de5438] |
|
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | A mirrored repository has at most one GitHub push mirror; repositories without one are skipped | [0c06789] |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ accepted plans.
|
|||||||
## Assumptions
|
## Assumptions
|
||||||
|
|
||||||
- The Gitea instance has Actions enabled and an `ubuntu-latest` runner with `python3`.
|
- The Gitea instance has Actions enabled and an `ubuntu-latest` runner with `python3`.
|
||||||
- Each mirrored repository has exactly one GitHub push mirror.
|
- A mirrored repository has at most one GitHub push mirror. Repositories without a GitHub mirror are skipped successfully.
|
||||||
- S01 (Product Owner) and S05 (DevOps owner and security authority) are both maintainers.
|
- S01 (Product Owner) and S05 (DevOps owner and security authority) are both maintainers.
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
@@ -149,3 +149,4 @@ Proceed — the first milestone fixes a known defect in the only existing workfl
|
|||||||
|
|
||||||
[SA-001]: ./stakeholder-analysis.md
|
[SA-001]: ./stakeholder-analysis.md
|
||||||
[4de5438]: https://git.tirsystem.com/TirSystem/github-action/commit/4de5438a88b4bbf18b165f52f797d1a52af89f6d
|
[4de5438]: https://git.tirsystem.com/TirSystem/github-action/commit/4de5438a88b4bbf18b165f52f797d1a52af89f6d
|
||||||
|
[0c06789]: https://git.tirsystem.com/TirSystem/github-action/commit/0c06789a2779382672712cd483f4964b28a0ebe9
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
## Version History
|
## Version History
|
||||||
| Date | Status | Author | Reviewer | Change | Commit |
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 2026-10-03 | Accepted | Jens Tirsvad Nielsen | S01 | Owner is S05 (security authority); S01 remains approving reviewer | [4de5438] |
|
| 2026-10-03 | Deprecated | Jens Tirsvad Nielsen | S01 | Recorded decisions for tasks 1 and 3 | [cbb9688] |
|
||||||
| 2026-10-03 | Proposed | Jens Tirsvad Nielsen | S01 | Recorded decisions for tasks 1 and 3 | [cbb9688] |
|
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Task 1 decision amended: zero GitHub mirrors is a successful skip<br>Task 5 tests cover zero or several mirrors accordingly | [0c06789] |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -62,16 +62,16 @@ successful manual run on the Gitea instance.
|
|||||||
|
|
||||||
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
|
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| 1 | Decide behavior for an invalid push mirror response | The committed workflow fails with an error when Gitea returns a non-list push mirror response. The uncommitted scoped copy instead prints a message and tries to exit successfully, and the README diagram showed that. Choose fail or skip, record the decision, and align code and README. Decision: skip with a visible warning and a successful run, following the maintainer's edit to the scoped copy; zero, several or malformed GitHub mirrors still fail. | No | |
|
| 1 | Decide behavior for an invalid push mirror response | The committed workflow fails with an error when Gitea returns a non-list push mirror response. The uncommitted scoped copy instead prints a message and tries to exit successfully, and the README diagram showed that. Choose fail or skip, record the decision, and align code and README. Decision: skip with a visible warning and a successful run, following the maintainer's edit to the scoped copy; several or malformed GitHub mirrors still fail. Amended 2026-10-10: zero GitHub mirrors is also a successful skip, because not every Gitea repository has a mirror; the GitHub secret is then not read. | No | |
|
||||||
| 2 | Fix the Python syntax error in the scoped workflow | `exit 0` is not valid Python, so the whole embedded script fails to compile in the scoped copy. Replace it according to the decision in task 1 (`sys.exit(0)` also needs `import sys`). | No | |
|
| 2 | Fix the Python syntax error in the scoped workflow | `exit 0` is not valid Python, so the whole embedded script fails to compile in the scoped copy. Replace it according to the decision in task 1 (`sys.exit(0)` also needs `import sys`). | No | |
|
||||||
| 3 | Reduce the workflow to one canonical source | The same workflow exists in `src/` and `.gitea/scoped_workflows/` (and a legacy copy that is no longer documented), and the scoped copy has diverged. Choose the canonical location, and generate or remove the others. Decision: `.gitea/scoped_workflows/` is canonical because the script must be embedded in the YAML to work as a scoped workflow; the `src/` copy is removed. | No | |
|
| 3 | Reduce the workflow to one canonical source | The same workflow exists in `src/` and `.gitea/scoped_workflows/` (and a legacy copy that is no longer documented), and the scoped copy has diverged. Choose the canonical location, and generate or remove the others. Decision: `.gitea/scoped_workflows/` is canonical because the script must be embedded in the YAML to work as a scoped workflow; the `src/` copy is removed. | No | |
|
||||||
| 4 | Add static validation of workflow files | Parse each workflow YAML and compile its embedded Python in an automated check that runs on pull requests, so defects such as task 2 fail before merge. | No | |
|
| 4 | Add static validation of workflow files | Parse each workflow YAML and compile its embedded Python in an automated check that runs on pull requests, so defects such as task 2 fail before merge. | No | |
|
||||||
| 5 | Add offline unit tests for the sync logic | Move credential and mirror URL parsing into testable code and test bare token, JSON token, SSH and HTTPS mirror addresses, and zero or several mirrors. Replace `tests/test_.ps1`, which probes a hard-coded real repository and reads `.env`. | No | |
|
| 5 | Add offline unit tests for the sync logic | Move credential and mirror URL parsing into testable code and test bare token, JSON token, SSH and HTTPS mirror addresses, zero mirrors (skipped successfully) and several mirrors (fail). Replace `tests/test_.ps1`, which probes a hard-coded real repository and reads `.env`. | No | |
|
||||||
| 6 | Keep the README accurate | Maintain the capability table (implemented, partial, planned), and align the sequence diagram with the final behavior from task 1. | No | |
|
| 6 | Keep the README accurate | Maintain the capability table (implemented, partial, planned), and align the sequence diagram with the final behavior from task 1. | No | |
|
||||||
| 7 | Verify a live run | Trigger the workflow manually on Gitea and compare the GitHub description and topics with the Gitea repository. | No | |
|
| 7 | Verify a live run | Trigger the workflow manually on Gitea and compare the GitHub description and topics with the Gitea repository. | No | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[BC-001]: ../business-case.md
|
[BC-001]: ../business-case.md
|
||||||
[4de5438]: https://git.tirsystem.com/TirSystem/github-action/commit/4de5438a88b4bbf18b165f52f797d1a52af89f6d
|
|
||||||
[cbb9688]: https://git.tirsystem.com/TirSystem/github-action/commit/cbb9688ed4217ee953d5843b846e2e79f22aaf45
|
[cbb9688]: https://git.tirsystem.com/TirSystem/github-action/commit/cbb9688ed4217ee953d5843b846e2e79f22aaf45
|
||||||
|
[0c06789]: https://git.tirsystem.com/TirSystem/github-action/commit/0c06789a2779382672712cd483f4964b28a0ebe9
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
## Version History
|
## Version History
|
||||||
| Date | Status | Author | Reviewer | Change | Commit |
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 2026-10-03 | Rejected | Jens Tirsvad Nielsen | S01 | Initial version<br>Added use case candidates and prioritisation appendix | [4de5438] |
|
| 2026-10-03 | Deprecated | Jens Tirsvad Nielsen | S01 | Owner of every gateway is S05<br>Actors updated | [4de5438] |
|
||||||
| 2026-10-03 | Accepted | Jens Tirsvad Nielsen | S01 | Owner of every gateway is S05<br>Actors updated | [4de5438] |
|
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | UC candidate 1: no GitHub mirror is a successful skip | [0c06789] |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@ no tests, no release process.
|
|||||||
|
|
||||||
- **Actor:** DevOps professional. **Goal:** the GitHub mirror shows the Gitea description and topics.
|
- **Actor:** DevOps professional. **Goal:** the GitHub mirror shows the Gitea description and topics.
|
||||||
- **Trigger:** push to `main`, manual dispatch, or daily at 03:17 UTC.
|
- **Trigger:** push to `main`, manual dispatch, or daily at 03:17 UTC.
|
||||||
- **Preconditions:** both secrets set; exactly one GitHub push mirror configured; runner available.
|
- **Preconditions:** both secrets set; at most one GitHub push mirror configured (none: the run is skipped successfully); runner available.
|
||||||
- **Success:** description and topics on GitHub equal those on Gitea.
|
- **Success:** description and topics on GitHub equal those on Gitea.
|
||||||
- **Main flow:** the workflow validates the secrets, reads description and topics from Gitea, finds the single GitHub mirror, updates the description, replaces the topics.
|
- **Main flow:** the workflow validates the secrets, reads description and topics from Gitea, finds the GitHub mirror (if none, ends successfully without syncing), updates the description, replaces the topics.
|
||||||
- **Alternatives and failures:** missing or invalid secret: fail with a message; zero or several GitHub mirrors: fail; non-list mirror response: behavior undecided (MIL-001 task 1); Gitea or GitHub API error: fail with the HTTP code.
|
- **Alternatives and failures:** missing or invalid secret: fail with a message; no GitHub mirror: successful run, nothing synced; several GitHub mirrors: fail; non-list mirror response: behavior undecided (MIL-001 task 1); Gitea or GitHub API error: fail with the HTTP code.
|
||||||
- **Dependencies:** none.
|
- **Dependencies:** none.
|
||||||
|
|
||||||
### UC candidate 2: Configure workflow credentials (P1)
|
### UC candidate 2: Configure workflow credentials (P1)
|
||||||
@@ -246,3 +246,4 @@ no tests, no release process.
|
|||||||
[Milestone MIL-003]: https://git.tirsystem.com/TirSystem/github-action/milestone/20
|
[Milestone MIL-003]: https://git.tirsystem.com/TirSystem/github-action/milestone/20
|
||||||
[Milestone MIL-004]: https://git.tirsystem.com/TirSystem/github-action/milestone/21
|
[Milestone MIL-004]: https://git.tirsystem.com/TirSystem/github-action/milestone/21
|
||||||
[4de5438]: https://git.tirsystem.com/TirSystem/github-action/commit/4de5438a88b4bbf18b165f52f797d1a52af89f6d
|
[4de5438]: https://git.tirsystem.com/TirSystem/github-action/commit/4de5438a88b4bbf18b165f52f797d1a52af89f6d
|
||||||
|
[0c06789]: https://git.tirsystem.com/TirSystem/github-action/commit/0c06789a2779382672712cd483f4964b28a0ebe9
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ The workflow runs a preflight and writes nothing to GitHub unless it passes:
|
|||||||
|
|
||||||
1. Both secrets exist and have the expected shape.
|
1. Both secrets exist and have the expected shape.
|
||||||
2. Gitea accepts the token and the repository is visible with it.
|
2. Gitea accepts the token and the repository is visible with it.
|
||||||
3. Exactly one GitHub push mirror is configured.
|
3. At most one GitHub push mirror is configured. With none, the run ends
|
||||||
|
successfully without syncing and the GitHub secret is not read.
|
||||||
4. GitHub accepts the token for the mirror repository **and** the token
|
4. GitHub accepts the token for the mirror repository **and** the token
|
||||||
reports administration access to it.
|
reports administration access to it.
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ Until delivery is verified, onboard a repository by copying the workflow (below)
|
|||||||
1. **Check the prerequisites** in the repository: Actions are enabled, and a
|
1. **Check the prerequisites** in the repository: Actions are enabled, and a
|
||||||
runner with the label `ubuntu-latest` and `python3` is online (see
|
runner with the label `ubuntu-latest` and `python3` is online (see
|
||||||
[Runners](#runners)).
|
[Runners](#runners)).
|
||||||
2. **Configure exactly one GitHub push mirror** in the repository settings
|
2. **Configure one GitHub push mirror** in the repository settings
|
||||||
(Settings, Repository, Mirror settings, Push mirror). The workflow fails
|
(Settings, Repository, Mirror settings, Push mirror). The workflow fails
|
||||||
when there are zero or several GitHub mirrors.
|
when there are several GitHub mirrors. With none, it succeeds without
|
||||||
|
syncing anything.
|
||||||
3. **Add the two secrets** in the repository (or organization) settings,
|
3. **Add the two secrets** in the repository (or organization) settings,
|
||||||
using the scopes in [credentials.md](credentials.md):
|
using the scopes in [credentials.md](credentials.md):
|
||||||
- `TOKEN_FOR_GITEA`
|
- `TOKEN_FOR_GITEA`
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ never starts, or stops before the step) is a **runner** problem.
|
|||||||
| `TOKEN_FOR_GITEA is missing or empty.` | configuration | Add the secret |
|
| `TOKEN_FOR_GITEA is missing or empty.` | configuration | Add the secret |
|
||||||
| `TOKEN_FOR_GITEA must contain a non-empty GITEA_TOKEN.` | configuration | The JSON form needs a `GITEA_TOKEN` key |
|
| `TOKEN_FOR_GITEA must contain a non-empty GITEA_TOKEN.` | configuration | The JSON form needs a `GITEA_TOKEN` key |
|
||||||
| `Could not determine the Gitea source repository.` | configuration | The run has no repository name; report as a defect |
|
| `Could not determine the Gitea source repository.` | configuration | The run has no repository name; report as a defect |
|
||||||
| `Expected exactly one GitHub push mirror ... found 0` | configuration | Add a GitHub push mirror in the repository settings |
|
| `Expected at most one GitHub push mirror ... found N` | configuration | Keep one GitHub push mirror |
|
||||||
| `Expected exactly one GitHub push mirror ... found N` | configuration | Keep one GitHub push mirror |
|
|
||||||
| `Could not determine the GitHub owner and repository ...` | configuration | The mirror address must look like `https://github.com/<owner>/<repo>.git` |
|
| `Could not determine the GitHub owner and repository ...` | configuration | The mirror address must look like `https://github.com/<owner>/<repo>.git` |
|
||||||
| `Gitea API request failed with HTTP 401` | credentials | Create a new Gitea token and update `TOKEN_FOR_GITEA` |
|
| `Gitea API request failed with HTTP 401` | credentials | Create a new Gitea token and update `TOKEN_FOR_GITEA` |
|
||||||
| `GitHub API request failed with HTTP 401` | credentials | Create a new GitHub token and update `CREDENTIALS_FOR_GITHUB` |
|
| `GitHub API request failed with HTTP 401` | credentials | Create a new GitHub token and update `CREDENTIALS_FOR_GITHUB` |
|
||||||
@@ -43,6 +42,11 @@ never starts, or stops before the step) is a **runner** problem.
|
|||||||
|
|
||||||
## Not an error
|
## Not an error
|
||||||
|
|
||||||
|
`No GitHub push mirror configured for <repo>; nothing to sync.` The run
|
||||||
|
succeeds. Not every Gitea repository has a GitHub mirror, so this is expected
|
||||||
|
for those. If the repository should have one, add it in the repository
|
||||||
|
settings.
|
||||||
|
|
||||||
`WARNING: Gitea returned an invalid push mirror list; GitHub metadata was not
|
`WARNING: Gitea returned an invalid push mirror list; GitHub metadata was not
|
||||||
synced.` The run succeeds but nothing was synced. Check that the Gitea
|
synced.` The run succeeds but nothing was synced. Check that the Gitea
|
||||||
version supports the push mirror API and re-run.
|
version supports the push mirror API and re-run.
|
||||||
|
|||||||
@@ -100,9 +100,8 @@ class TestFindGithubTargets:
|
|||||||
[{"remote_address": "https://gitlab.com/Org/other.git"}],
|
[{"remote_address": "https://gitlab.com/Org/other.git"}],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_fails_when_no_github_mirror_exists(self, sync, mirrors):
|
def test_returns_none_when_no_github_mirror_exists(self, sync, mirrors):
|
||||||
with pytest.raises(RuntimeError, match="found 0"):
|
assert sync["find_github_targets"](mirrors) is None
|
||||||
sync["find_github_targets"](mirrors)
|
|
||||||
|
|
||||||
def test_fails_when_several_github_mirrors_exist(self, sync):
|
def test_fails_when_several_github_mirrors_exist(self, sync):
|
||||||
mirrors = [
|
mirrors = [
|
||||||
@@ -249,16 +248,36 @@ class TestMain:
|
|||||||
assert all(call[0] == "GET" for call in api.calls)
|
assert all(call[0] == "GET" for call in api.calls)
|
||||||
assert "WARNING" in capsys.readouterr().out
|
assert "WARNING" in capsys.readouterr().out
|
||||||
|
|
||||||
def test_fails_before_any_request_when_credentials_are_missing(
|
@pytest.mark.parametrize(
|
||||||
|
"mirrors",
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
[{"remote_address": "https://gitlab.com/Org/other.git"}],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_succeeds_without_changes_when_no_github_mirror_exists(
|
||||||
|
self, sync, environment, monkeypatch, capsys, mirrors
|
||||||
|
):
|
||||||
|
monkeypatch.setenv("GITHUB_CREDENTIALS", "")
|
||||||
|
api = FakeApi(mirrors)
|
||||||
|
sync["request_json"] = api
|
||||||
|
|
||||||
|
assert sync["main"]() == 0
|
||||||
|
|
||||||
|
assert all(call[0] == "GET" for call in api.calls)
|
||||||
|
assert not any(call[1].startswith("https://api.github.com") for call in api.calls)
|
||||||
|
assert "No GitHub push mirror configured" in capsys.readouterr().out
|
||||||
|
|
||||||
|
def test_fails_before_any_change_when_github_credentials_are_missing(
|
||||||
self, sync, environment, monkeypatch
|
self, sync, environment, monkeypatch
|
||||||
):
|
):
|
||||||
monkeypatch.setenv("GITHUB_CREDENTIALS", "")
|
monkeypatch.setenv("GITHUB_CREDENTIALS", "")
|
||||||
api = FakeApi([])
|
api = FakeApi([{"remote_address": "git@github.com:Org/repo.git"}])
|
||||||
sync["request_json"] = api
|
sync["request_json"] = api
|
||||||
|
|
||||||
with pytest.raises(RuntimeError, match="CREDENTIALS_FOR_GITHUB"):
|
with pytest.raises(RuntimeError, match="CREDENTIALS_FOR_GITHUB"):
|
||||||
sync["main"]()
|
sync["main"]()
|
||||||
assert api.calls == []
|
assert all(call[0] == "GET" for call in api.calls)
|
||||||
|
|
||||||
def test_stops_before_any_change_when_github_token_cannot_administer(
|
def test_stops_before_any_change_when_github_token_cannot_administer(
|
||||||
self, sync, environment
|
self, sync, environment
|
||||||
|
|||||||
Reference in New Issue
Block a user