diff --git a/python_modules/libraries/dagster-github/dagster_github/resources.py b/python_modules/libraries/dagster-github/dagster_github/resources.py index 4c4d37c3f62db..e46e00ae7a2f7 100644 --- a/python_modules/libraries/dagster-github/dagster_github/resources.py +++ b/python_modules/libraries/dagster-github/dagster_github/resources.py @@ -161,6 +161,65 @@ def create_issue(self, repo_name, repo_owner, title, body, installation_id=None) installation_id=installation_id, ) + def create_ref( + self, + repo_name: str, + repo_owner: str, + source: str, + target: str, + installation_id=None, + ): + if installation_id is None: + installation_id = self.default_installation_id + res = self.execute( + query=""" + query get_repo_and_source_ref($repo_name: String!, $repo_owner: String!, $source: String!) { + repository(name: $repo_name, owner: $repo_owner) { + id + ref(qualifiedName: $source) { + target { + oid + } + } + } + } + """, + variables={ + "repo_name": repo_name, + "repo_owner": repo_owner, + "source": source, + }, + installation_id=installation_id, + ) + + branch = self.execute( + query=""" + mutation CreateRef($id: ID!, $name: String!, $oid: GitObjectID!) { + createRef(input: { + repositoryId: $id, + name: $name, + oid: $oid + }) { + clientMutationId, + ref { + id + name + target { + oid + } + } + } + } + """, + variables={ + "id": res["data"]["repository"]["id"], + "name": target, + "oid": res["data"]["repository"]["ref"]["target"]["oid"], + }, + installation_id=installation_id, + ) + return branch + class GithubResource(ConfigurableResource): github_app_id: int = Field( diff --git a/python_modules/libraries/dagster-github/dagster_github_tests/test_resources.py b/python_modules/libraries/dagster-github/dagster_github_tests/test_resources.py index 1ce7e32daada4..a88a97f7c09d5 100644 --- a/python_modules/libraries/dagster-github/dagster_github_tests/test_resources.py +++ b/python_modules/libraries/dagster-github/dagster_github_tests/test_resources.py @@ -129,6 +129,58 @@ def github_op(github_client_resource: GithubResource): assert result.success +@responses.activate +def test_github_resource_create_ref(): + @op + def github_op(github_client_resource: GithubResource): + github = github_client_resource.get_client() + assert github + with responses.RequestsMock() as rsps: + rsps.add( + rsps.POST, + "https://api.github.com/app/installations/123/access_tokens", + status=201, + json={ + "token": "fake_token", + "expires_at": "2016-07-11T22:14:10Z", + }, + ) + rsps.add( + rsps.POST, + "https://api.github.com/graphql", + status=200, + json={ + "data": { + "repository": {"id": 123, "ref": {"target": {"oid": "refs/heads/master"}}} + }, + }, + ) + rsps.add( + rsps.POST, + "https://api.github.com/graphql", + status=200, + json={}, + ) + github.create_ref( + repo_name="dagster", + repo_owner="dagster-io", + source="refs/heads/master", + target="refs/heads/test-branch", + ) + + result = wrap_op_in_graph_and_execute( + github_op, + resources={ + "github_client_resource": GithubResource( + github_app_id=123, + github_app_private_rsa_key=FAKE_PRIVATE_RSA_KEY, + github_installation_id=123, + ) + }, + ) + assert result.success + + @responses.activate def test_github_resource_execute(): @op