goose-py 0.7.0__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- goose_py-0.7.1/.github/workflows/publish.yml +48 -0
- goose_py-0.7.1/Makefile +9 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/PKG-INFO +1 -1
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/agent.py +7 -25
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/conversation.py +2 -10
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/flow.py +3 -4
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/state.py +5 -15
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/task.py +5 -12
- {goose_py-0.7.0 → goose_py-0.7.1}/pyproject.toml +3 -2
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/conftest.py +1 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_agent.py +5 -11
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_complex_flow_arguments.py +1 -2
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_downstream_task.py +1 -3
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_jamming.py +2 -4
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_looping.py +2 -6
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_state.py +1 -3
- {goose_py-0.7.0 → goose_py-0.7.1}/uv.lock +2 -2
- goose_py-0.7.0/.github/workflows/publish.yml +0 -75
- {goose_py-0.7.0 → goose_py-0.7.1}/.envrc +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/.gitignore +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/.python-version +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/.stubs/jsonpath_ng/__init__.pyi +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/.stubs/litellm/__init__.pyi +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/README.md +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/__init__.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/result.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/store.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/types/__init__.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/_internal/types/agent.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/agent.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/errors.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/flow.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/py.typed +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/goose/runs.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/__init__.py +0 -0
- {goose_py-0.7.0 → goose_py-0.7.1}/tests/test_regenerate.py +0 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
name: CI/CD
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
tags:
|
8
|
+
- "v*"
|
9
|
+
pull_request:
|
10
|
+
branches:
|
11
|
+
- main
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
publish:
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
|
17
|
+
permissions:
|
18
|
+
id-token: write
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v4
|
22
|
+
with:
|
23
|
+
fetch-depth: 0
|
24
|
+
|
25
|
+
- name: Setup Python
|
26
|
+
uses: actions/setup-python@v5
|
27
|
+
with:
|
28
|
+
python-version-file: .python-version
|
29
|
+
|
30
|
+
- name: Setup UV
|
31
|
+
uses: astral-sh/setup-uv@v5
|
32
|
+
with:
|
33
|
+
version: "0.5.25"
|
34
|
+
|
35
|
+
- name: Initialize environment
|
36
|
+
run: uv sync --all-extras --dev
|
37
|
+
|
38
|
+
- name: Run tests
|
39
|
+
run: uv run pytest
|
40
|
+
env:
|
41
|
+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
42
|
+
|
43
|
+
- name: Build package
|
44
|
+
run: uv build
|
45
|
+
|
46
|
+
- name: Publish package
|
47
|
+
run: uv publish
|
48
|
+
continue-on-error: true
|
goose_py-0.7.1/Makefile
ADDED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: goose-py
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.1
|
4
4
|
Summary: A tool for AI workflows based on human-computer collaboration and structured output.
|
5
5
|
Author-email: Nash Taylor <nash@chelle.ai>, Joshua Cook <joshua@chelle.ai>, Michael Sankur <michael@chelle.ai>
|
6
6
|
Requires-Python: >=3.12
|
@@ -65,20 +65,12 @@ class AgentResponse[R: BaseModel | str](BaseModel):
|
|
65
65
|
@computed_field
|
66
66
|
@property
|
67
67
|
def input_cost(self) -> float:
|
68
|
-
return
|
69
|
-
self.INPUT_CENTS_PER_MILLION_TOKENS[self.model]
|
70
|
-
* self.input_tokens
|
71
|
-
/ 1_000_000
|
72
|
-
)
|
68
|
+
return self.INPUT_CENTS_PER_MILLION_TOKENS[self.model] * self.input_tokens / 1_000_000
|
73
69
|
|
74
70
|
@computed_field
|
75
71
|
@property
|
76
72
|
def output_cost(self) -> float:
|
77
|
-
return
|
78
|
-
self.OUTPUT_CENTS_PER_MILLION_TOKENS[self.model]
|
79
|
-
* self.output_tokens
|
80
|
-
/ 1_000_000
|
81
|
-
)
|
73
|
+
return self.OUTPUT_CENTS_PER_MILLION_TOKENS[self.model] * self.output_tokens / 1_000_000
|
82
74
|
|
83
75
|
@computed_field
|
84
76
|
@property
|
@@ -100,15 +92,9 @@ class AgentResponse[R: BaseModel | str](BaseModel):
|
|
100
92
|
for part in message["content"]:
|
101
93
|
if part["type"] == "image_url":
|
102
94
|
part["image_url"] = "__MEDIA__"
|
103
|
-
minimized_input_messages = [
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
output_message = (
|
108
|
-
self.response.model_dump_json()
|
109
|
-
if isinstance(self.response, BaseModel)
|
110
|
-
else self.response
|
111
|
-
)
|
95
|
+
minimized_input_messages = [json.dumps(message) for message in minimized_input_messages]
|
96
|
+
|
97
|
+
output_message = self.response.model_dump_json() if isinstance(self.response, BaseModel) else self.response
|
112
98
|
|
113
99
|
return {
|
114
100
|
"run_id": self.run_id,
|
@@ -161,9 +147,7 @@ class Agent:
|
|
161
147
|
|
162
148
|
if response_model is TextResult:
|
163
149
|
response = await acompletion(model=model.value, messages=rendered_messages)
|
164
|
-
parsed_response = response_model.model_validate(
|
165
|
-
{"text": response.choices[0].message.content}
|
166
|
-
)
|
150
|
+
parsed_response = response_model.model_validate({"text": response.choices[0].message.content})
|
167
151
|
else:
|
168
152
|
response = await acompletion(
|
169
153
|
model=model.value,
|
@@ -174,9 +158,7 @@ class Agent:
|
|
174
158
|
"enforce_validation": True,
|
175
159
|
},
|
176
160
|
)
|
177
|
-
parsed_response = response_model.model_validate_json(
|
178
|
-
response.choices[0].message.content
|
179
|
-
)
|
161
|
+
parsed_response = response_model.model_validate_json(response.choices[0].message.content)
|
180
162
|
|
181
163
|
end_time = datetime.now()
|
182
164
|
agent_response = AgentResponse(
|
@@ -24,18 +24,10 @@ class Conversation[R: Result](BaseModel):
|
|
24
24
|
messages.append(self.context.render())
|
25
25
|
|
26
26
|
for message_index in range(len(self.user_messages)):
|
27
|
-
messages.append(
|
28
|
-
AssistantMessage(
|
29
|
-
text=self.result_messages[message_index].model_dump_json()
|
30
|
-
).render()
|
31
|
-
)
|
27
|
+
messages.append(AssistantMessage(text=self.result_messages[message_index].model_dump_json()).render())
|
32
28
|
messages.append(self.user_messages[message_index].render())
|
33
29
|
|
34
30
|
if len(self.result_messages) > len(self.user_messages):
|
35
|
-
messages.append(
|
36
|
-
AssistantMessage(
|
37
|
-
text=self.result_messages[-1].model_dump_json()
|
38
|
-
).render()
|
39
|
-
)
|
31
|
+
messages.append(AssistantMessage(text=self.result_messages[-1].model_dump_json()).render())
|
40
32
|
|
41
33
|
return messages
|
@@ -1,6 +1,7 @@
|
|
1
|
+
from collections.abc import AsyncIterator, Awaitable, Callable
|
1
2
|
from contextlib import asynccontextmanager
|
2
3
|
from types import CodeType
|
3
|
-
from typing import
|
4
|
+
from typing import Protocol, overload
|
4
5
|
|
5
6
|
from goose._internal.agent import Agent, IAgentLogger
|
6
7
|
from goose._internal.conversation import Conversation
|
@@ -13,9 +14,7 @@ from goose.errors import Honk
|
|
13
14
|
class IAdapter[ResultT: Result](Protocol):
|
14
15
|
__code__: CodeType
|
15
16
|
|
16
|
-
async def __call__(
|
17
|
-
self, *, conversation: Conversation[ResultT], agent: Agent
|
18
|
-
) -> ResultT: ...
|
17
|
+
async def __call__(self, *, conversation: Conversation[ResultT], agent: Agent) -> ResultT: ...
|
19
18
|
|
20
19
|
|
21
20
|
class Flow[**P]:
|
@@ -97,23 +97,17 @@ class FlowRun:
|
|
97
97
|
matching_nodes: list[NodeState[R]] = []
|
98
98
|
for key, node_state in self._node_states.items():
|
99
99
|
if key[0] == task.name:
|
100
|
-
matching_nodes.append(
|
101
|
-
NodeState[task.result_type].model_validate_json(node_state)
|
102
|
-
)
|
100
|
+
matching_nodes.append(NodeState[task.result_type].model_validate_json(node_state))
|
103
101
|
return sorted(matching_nodes, key=lambda node: node.index)
|
104
102
|
|
105
103
|
def get[R: Result](self, *, task: "Task[Any, R]", index: int = 0) -> NodeState[R]:
|
106
|
-
if (
|
107
|
-
existing_node_state := self._node_states.get((task.name, index))
|
108
|
-
) is not None:
|
104
|
+
if (existing_node_state := self._node_states.get((task.name, index))) is not None:
|
109
105
|
return NodeState[task.result_type].model_validate_json(existing_node_state)
|
110
106
|
else:
|
111
107
|
return NodeState[task.result_type](
|
112
108
|
task_name=task.name,
|
113
109
|
index=index,
|
114
|
-
conversation=Conversation[task.result_type](
|
115
|
-
user_messages=[], result_messages=[]
|
116
|
-
),
|
110
|
+
conversation=Conversation[task.result_type](user_messages=[], result_messages=[]),
|
117
111
|
last_hash=0,
|
118
112
|
)
|
119
113
|
|
@@ -143,9 +137,7 @@ class FlowRun:
|
|
143
137
|
self._last_requested_indices = {}
|
144
138
|
self._flow_name = flow_name
|
145
139
|
self._id = run_id
|
146
|
-
self._agent = Agent(
|
147
|
-
flow_name=self.flow_name, run_id=self.id, logger=agent_logger
|
148
|
-
)
|
140
|
+
self._agent = Agent(flow_name=self.flow_name, run_id=self.id, logger=agent_logger)
|
149
141
|
|
150
142
|
def end(self) -> None:
|
151
143
|
self._last_requested_indices = {}
|
@@ -177,9 +169,7 @@ class FlowRun:
|
|
177
169
|
return flow_run
|
178
170
|
|
179
171
|
|
180
|
-
_current_flow_run: ContextVar[FlowRun | None] = ContextVar(
|
181
|
-
"current_flow_run", default=None
|
182
|
-
)
|
172
|
+
_current_flow_run: ContextVar[FlowRun | None] = ContextVar("current_flow_run", default=None)
|
183
173
|
|
184
174
|
|
185
175
|
def get_current_flow_run() -> FlowRun | None:
|
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Awaitable, Callable
|
2
|
+
from typing import overload
|
2
3
|
|
3
4
|
from goose._internal.agent import Agent, GeminiModel, SystemMessage, UserMessage
|
4
5
|
from goose._internal.conversation import Conversation
|
@@ -33,9 +34,7 @@ class Task[**P, R: Result]:
|
|
33
34
|
def name(self) -> str:
|
34
35
|
return self._generator.__name__
|
35
36
|
|
36
|
-
async def generate(
|
37
|
-
self, state: NodeState[R], *args: P.args, **kwargs: P.kwargs
|
38
|
-
) -> R:
|
37
|
+
async def generate(self, state: NodeState[R], *args: P.args, **kwargs: P.kwargs) -> R:
|
39
38
|
state_hash = self.__hash_task_call(*args, **kwargs)
|
40
39
|
if state_hash != state.last_hash:
|
41
40
|
result = await self._generator(*args, **kwargs)
|
@@ -58,9 +57,7 @@ class Task[**P, R: Result]:
|
|
58
57
|
node_state.set_context(context=context)
|
59
58
|
node_state.add_user_message(message=user_message)
|
60
59
|
|
61
|
-
result = await self.__adapt(
|
62
|
-
conversation=node_state.conversation, agent=flow_run.agent
|
63
|
-
)
|
60
|
+
result = await self.__adapt(conversation=node_state.conversation, agent=flow_run.agent)
|
64
61
|
node_state.add_result(result=result)
|
65
62
|
flow_run.add_node_state(node_state)
|
66
63
|
|
@@ -97,11 +94,7 @@ class Task[**P, R: Result]:
|
|
97
94
|
|
98
95
|
def __hash_task_call(self, *args: P.args, **kwargs: P.kwargs) -> int:
|
99
96
|
try:
|
100
|
-
to_hash = str(
|
101
|
-
tuple(args)
|
102
|
-
+ tuple(kwargs.values())
|
103
|
-
+ (self._generator.__code__, self._adapter_model)
|
104
|
-
)
|
97
|
+
to_hash = str(tuple(args) + tuple(kwargs.values()) + (self._generator.__code__, self._adapter_model))
|
105
98
|
return hash(to_hash)
|
106
99
|
except TypeError:
|
107
100
|
raise Honk(f"Unhashable argument to task {self.name}: {args} {kwargs}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "goose-py"
|
3
|
-
version = "0.7.
|
3
|
+
version = "0.7.1"
|
4
4
|
description = "A tool for AI workflows based on human-computer collaboration and structured output."
|
5
5
|
readme = "README.md"
|
6
6
|
authors = [
|
@@ -38,6 +38,7 @@ exclude = [
|
|
38
38
|
".venv",
|
39
39
|
"**/.venv",
|
40
40
|
"notebooks",
|
41
|
+
".stubs",
|
41
42
|
]
|
42
43
|
force-exclude = true
|
43
44
|
line-length = 120
|
@@ -61,12 +62,12 @@ pythonVersion = "3.12"
|
|
61
62
|
typeCheckingMode = "strict"
|
62
63
|
reportMissingModuleSource = false
|
63
64
|
useLibraryCodeForTypes = false
|
64
|
-
reportImportCycles = true
|
65
65
|
reportUnknownMemberType = false
|
66
66
|
reportUnknownVariableType = false
|
67
67
|
stubPath = ".stubs"
|
68
68
|
venvPath = "."
|
69
69
|
venv = ".venv"
|
70
|
+
exclude = ["goose/__init__.py", ".venv", "notebooks"]
|
70
71
|
|
71
72
|
[tool.pytest.ini_options]
|
72
73
|
filterwarnings = [
|
@@ -5,26 +5,20 @@ from pytest_mock import MockerFixture
|
|
5
5
|
|
6
6
|
from goose import TextResult, flow, task
|
7
7
|
from goose._internal.agent import Agent, AgentResponse, IAgentLogger
|
8
|
-
from goose.
|
8
|
+
from goose.agent import GeminiModel, TextMessagePart, UserMessage
|
9
9
|
|
10
10
|
|
11
11
|
class MockLiteLLMResponse:
|
12
|
-
def __init__(
|
13
|
-
self, *, response: str, prompt_tokens: int, completion_tokens: int
|
14
|
-
) -> None:
|
12
|
+
def __init__(self, *, response: str, prompt_tokens: int, completion_tokens: int) -> None:
|
15
13
|
self.choices = [Mock(message=Mock(content=response))]
|
16
|
-
self.usage = Mock(
|
17
|
-
prompt_tokens=prompt_tokens, completion_tokens=completion_tokens
|
18
|
-
)
|
14
|
+
self.usage = Mock(prompt_tokens=prompt_tokens, completion_tokens=completion_tokens)
|
19
15
|
|
20
16
|
|
21
17
|
@pytest.fixture
|
22
18
|
def mock_litellm(mocker: MockerFixture) -> Mock:
|
23
19
|
return mocker.patch(
|
24
|
-
"goose.
|
25
|
-
return_value=MockLiteLLMResponse(
|
26
|
-
response="Hello", prompt_tokens=10, completion_tokens=10
|
27
|
-
),
|
20
|
+
"goose._internal.agent.acompletion",
|
21
|
+
return_value=MockLiteLLMResponse(response="Hello", prompt_tokens=10, completion_tokens=10),
|
28
22
|
)
|
29
23
|
|
30
24
|
|
@@ -12,9 +12,7 @@ class GeneratedWord(Result):
|
|
12
12
|
|
13
13
|
@task
|
14
14
|
async def generate_random_word(*, n_characters: int) -> GeneratedWord:
|
15
|
-
return GeneratedWord(
|
16
|
-
word="".join(random.sample(string.ascii_lowercase, n_characters))
|
17
|
-
)
|
15
|
+
return GeneratedWord(word="".join(random.sample(string.ascii_lowercase, n_characters)))
|
18
16
|
|
19
17
|
|
20
18
|
@task
|
@@ -6,7 +6,7 @@ import pytest
|
|
6
6
|
from pytest_mock import MockerFixture
|
7
7
|
|
8
8
|
from goose import Result, flow, task
|
9
|
-
from goose.
|
9
|
+
from goose.agent import SystemMessage, TextMessagePart, UserMessage
|
10
10
|
|
11
11
|
|
12
12
|
class GeneratedWord(Result):
|
@@ -19,9 +19,7 @@ class GeneratedSentence(Result):
|
|
19
19
|
|
20
20
|
@task
|
21
21
|
async def generate_random_word(*, n_characters: int) -> GeneratedWord:
|
22
|
-
return GeneratedWord(
|
23
|
-
word="".join(random.sample(string.ascii_lowercase, n_characters))
|
24
|
-
)
|
22
|
+
return GeneratedWord(word="".join(random.sample(string.ascii_lowercase, n_characters)))
|
25
23
|
|
26
24
|
|
27
25
|
@pytest.fixture
|
@@ -31,9 +31,7 @@ async def number_of_learning_outcomes() -> NumberOfLearningOutcomes:
|
|
31
31
|
|
32
32
|
|
33
33
|
@task
|
34
|
-
async def learning_outcome(
|
35
|
-
*, objective: CourseObjective, previous_outcomes: list[LearningOutcome]
|
36
|
-
) -> LearningOutcome:
|
34
|
+
async def learning_outcome(*, objective: CourseObjective, previous_outcomes: list[LearningOutcome]) -> LearningOutcome:
|
37
35
|
return LearningOutcome(outcome="Learn Python")
|
38
36
|
|
39
37
|
|
@@ -48,9 +46,7 @@ async def course_content() -> None:
|
|
48
46
|
num_outcomes = await number_of_learning_outcomes()
|
49
47
|
outcomes: list[LearningOutcome] = []
|
50
48
|
for _ in range(num_outcomes.number):
|
51
|
-
outcomes.append(
|
52
|
-
await learning_outcome(objective=objective, previous_outcomes=outcomes)
|
53
|
-
)
|
49
|
+
outcomes.append(await learning_outcome(objective=objective, previous_outcomes=outcomes))
|
54
50
|
|
55
51
|
for outcome in outcomes:
|
56
52
|
await quiz_question(outcome=outcome.outcome)
|
@@ -17,9 +17,7 @@ class GeneratedSentence(Result):
|
|
17
17
|
|
18
18
|
@task
|
19
19
|
async def generate_random_word(*, n_characters: int) -> GeneratedWord:
|
20
|
-
return GeneratedWord(
|
21
|
-
word="".join(random.sample(string.ascii_lowercase, n_characters))
|
22
|
-
)
|
20
|
+
return GeneratedWord(word="".join(random.sample(string.ascii_lowercase, n_characters)))
|
23
21
|
|
24
22
|
|
25
23
|
@task
|
@@ -1,75 +0,0 @@
|
|
1
|
-
name: CI/CD
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
tags:
|
8
|
-
- "v*"
|
9
|
-
pull_request:
|
10
|
-
branches:
|
11
|
-
- main
|
12
|
-
|
13
|
-
jobs:
|
14
|
-
test:
|
15
|
-
runs-on: ubuntu-latest
|
16
|
-
|
17
|
-
steps:
|
18
|
-
- uses: actions/checkout@v4
|
19
|
-
with:
|
20
|
-
fetch-depth: 0
|
21
|
-
|
22
|
-
- name: Set up Python
|
23
|
-
uses: actions/setup-python@v4
|
24
|
-
with:
|
25
|
-
python-version: "3.12"
|
26
|
-
|
27
|
-
- name: Install Poetry
|
28
|
-
uses: snok/install-poetry@v1
|
29
|
-
with:
|
30
|
-
version: 1.8.5
|
31
|
-
virtualenvs-create: true
|
32
|
-
virtualenvs-in-project: true
|
33
|
-
|
34
|
-
- name: Install dependencies
|
35
|
-
run: poetry install --all-extras
|
36
|
-
|
37
|
-
- name: Run tests
|
38
|
-
run: poetry run pytest tests
|
39
|
-
env:
|
40
|
-
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
41
|
-
|
42
|
-
publish:
|
43
|
-
needs: test
|
44
|
-
runs-on: ubuntu-latest
|
45
|
-
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main')
|
46
|
-
permissions:
|
47
|
-
id-token: write
|
48
|
-
contents: read
|
49
|
-
|
50
|
-
steps:
|
51
|
-
- uses: actions/checkout@v4
|
52
|
-
with:
|
53
|
-
fetch-depth: 0
|
54
|
-
|
55
|
-
- name: Set up Python
|
56
|
-
uses: actions/setup-python@v4
|
57
|
-
with:
|
58
|
-
python-version: "3.12"
|
59
|
-
|
60
|
-
- name: Install Poetry
|
61
|
-
uses: snok/install-poetry@v1
|
62
|
-
with:
|
63
|
-
version: 1.8.5
|
64
|
-
virtualenvs-create: true
|
65
|
-
virtualenvs-in-project: true
|
66
|
-
|
67
|
-
- name: Install dependencies
|
68
|
-
run: poetry install --all-extras
|
69
|
-
|
70
|
-
- name: Build package
|
71
|
-
run: poetry build
|
72
|
-
|
73
|
-
- name: Publish to PyPI
|
74
|
-
if: startsWith(github.ref, 'refs/tags/')
|
75
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|