Skip to content

Commit 5d637f7

Browse files
authored
Merge pull request #5 from strawberry-graphql/codex/lazy-plugin-secrets
2 parents b8aac66 + b45d8ae commit 5d637f7

File tree

5 files changed

+60
-18
lines changed

5 files changed

+60
-18
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Plugin path:
4444
strawberry_autopub_plugins.invite_contributors:InviteContributorsPlugin
4545
```
4646

47-
Required environment variables:
47+
Environment variables used when the plugin needs to call the GitHub API:
4848

4949
- `GITHUB_TOKEN`
5050
- `GITHUB_REPOSITORY`
@@ -86,7 +86,7 @@ Plugin path:
8686
strawberry_autopub_plugins.typefully:TypefullyPlugin
8787
```
8888

89-
Required environment variables:
89+
Environment variables used when the plugin needs to create a Typefully draft:
9090

9191
- `TYPEFULLY_API_KEY`
9292

@@ -95,6 +95,7 @@ Optional environment variables:
9595
- `TYPEFULLY_SOCIAL_SET_ID`
9696

9797
You can provide the social set ID either through `social-set-id` in config or `TYPEFULLY_SOCIAL_SET_ID`.
98+
In `dry-run` mode, the plugin can render the request body without requiring either value.
9899

99100
Example config:
100101

src/strawberry_autopub_plugins/invite_contributors.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,19 @@ class InviteContributorsPlugin(AutopubPlugin):
4848
id = "invite_contributors"
4949
Config = InviteContributorsConfig
5050

51-
def __init__(self) -> None:
52-
self.github_token = os.environ.get("GITHUB_TOKEN")
53-
self.repository_name = os.environ.get("GITHUB_REPOSITORY")
54-
55-
if not self.github_token:
51+
@property
52+
def github_token(self) -> str:
53+
github_token = os.environ.get("GITHUB_TOKEN")
54+
if not github_token:
5655
raise AutopubException("GITHUB_TOKEN environment variable is required")
56+
return github_token
5757

58-
if not self.repository_name:
58+
@property
59+
def repository_name(self) -> str:
60+
repository_name = os.environ.get("GITHUB_REPOSITORY")
61+
if not repository_name:
5962
raise AutopubException("GITHUB_REPOSITORY environment variable is required")
63+
return repository_name
6064

6165
@cached_property
6266
def _github(self) -> Github:

src/strawberry_autopub_plugins/typefully.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ class TypefullyPlugin(AutopubPlugin):
5555
Config = TypefullyConfig
5656
BASE_URL = "https://api.typefully.com"
5757

58-
def __init__(self) -> None:
59-
self.api_key = os.environ.get("TYPEFULLY_API_KEY")
60-
61-
if not self.api_key:
58+
@property
59+
def api_key(self) -> str:
60+
api_key = os.environ.get("TYPEFULLY_API_KEY")
61+
if not api_key:
6262
raise _autopub_error("TYPEFULLY_API_KEY environment variable is required")
63+
return api_key
6364

6465
def _format_message(
6566
self,
@@ -197,17 +198,17 @@ def _create_draft(self, body: dict[str, object]) -> None:
197198
) from exc
198199

199200
def post_publish(self, release_info: ReleaseInfo) -> None:
200-
if not self.config.social_set_id:
201-
raise _autopub_error(
202-
"social-set-id config or TYPEFULLY_SOCIAL_SET_ID environment variable is required"
203-
)
204-
205201
body = self._build_request_body(release_info)
206202

207203
if self.config.dry_run:
208204
print(f"[typefully] dry run — request body: {body}")
209205
return
210206

207+
if not self.config.social_set_id:
208+
raise _autopub_error(
209+
"social-set-id config or TYPEFULLY_SOCIAL_SET_ID environment variable is required"
210+
)
211+
211212
self._create_draft(body)
212213

213214

tests/test_invite_contributors.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
from unittest.mock import MagicMock
44

5+
import pytest
56
from github.GithubException import GithubException
67

8+
from autopub.exceptions import AutopubException
79
from autopub.types import ReleaseInfo
810
from strawberry_autopub_plugins.invite_contributors import (
911
KNOWN_BOT_EXCLUSIONS,
@@ -144,3 +146,21 @@ def test_default_config_skips_known_bot_usernames(monkeypatch) -> None:
144146
assert plugin.config.skip_bots is True
145147
assert plugin.config.exclude_users == KNOWN_BOT_EXCLUSIONS
146148
assert filtered == ["author"]
149+
150+
151+
def test_missing_github_env_is_only_checked_when_needed(monkeypatch) -> None:
152+
monkeypatch.delenv("GITHUB_TOKEN", raising=False)
153+
monkeypatch.delenv("GITHUB_REPOSITORY", raising=False)
154+
155+
plugin = InviteContributorsPlugin()
156+
plugin.validate_config({})
157+
158+
plugin.pull_request = None
159+
plugin.post_publish(_release_info())
160+
161+
plugin.pull_request = MagicMock()
162+
plugin.pull_request.user.login = "author"
163+
plugin.pull_request.get_commits.return_value = []
164+
165+
with pytest.raises(AutopubException, match="GITHUB_TOKEN"):
166+
plugin.post_publish(_release_info())

tests/test_typefully.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,24 @@ def _get_request_body(mock_urlopen) -> dict:
7272
def test_missing_api_key_raises(monkeypatch) -> None:
7373
monkeypatch.delenv("TYPEFULLY_API_KEY", raising=False)
7474

75+
plugin = TypefullyPlugin()
76+
plugin.validate_config({"plugin_config": {"typefully": {"social-set-id": "abc-123"}}})
77+
7578
with pytest.raises(AutopubException, match="TYPEFULLY_API_KEY"):
76-
TypefullyPlugin()
79+
plugin.post_publish(_release_info())
80+
81+
82+
def test_dry_run_does_not_require_api_key_or_social_set_id(monkeypatch, capsys) -> None:
83+
monkeypatch.delenv("TYPEFULLY_API_KEY", raising=False)
84+
monkeypatch.delenv("TYPEFULLY_SOCIAL_SET_ID", raising=False)
85+
86+
plugin = TypefullyPlugin()
87+
plugin.validate_config({"plugin_config": {"typefully": {"dry-run": True}}})
88+
89+
plugin.post_publish(_release_info())
90+
91+
output = capsys.readouterr().out
92+
assert "[typefully] dry run" in output
7793

7894

7995
@patch("strawberry_autopub_plugins.typefully.urlopen")

0 commit comments

Comments
 (0)