Skip to content

feat: add pulumi-devin provider and hagaym1 as maintainer - #559

Merged
tmeckel merged 1 commit into
pulumiverse:mainfrom
hagaym1:feat/add-pulumi-devin
Aug 24, 2026
Merged

tmeckel merged 1 commit into
pulumiverse:mainfrom
hagaym1:feat/add-pulumi-devin

Conversation

@hagaym1

@hagaym1 hagaym1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Follows up pulumiverse/.github#46, per @tmeckel's pointer to #353.

Adds the repository entry and myself as its maintainer, alongside pulumi-unleash. type and
workflows match the other TF-bridged providers, since it is built from
pulumi-tf-provider-boilerplate with workflows generated by pulumiverse/projen-pulumi-providers.

State of the provider

It already exists and works at https://github.com/hagaym1/pulumi-devin: 12 commits, 18 resources and
6 data sources bridged, all four SDKs building, and CI green except publish_sdk, which fails only
because a personal repo has no registry tokens. Nothing published, no tags cut, so package identity is
still open.

Learning from #542, the three onboarding steps I raised in
pulumiverse/projen-pulumi-providers#8 are applied up front here, which is why this one did not start
out red: the ci-mgmt target points at the fork, github-app.enabled: false, and a root mise.toml
declares the terraform converter. Package names are already @pulumiverse/devin /
pulumiverse_devin / Pulumiverse.Devin rather than the boilerplate's @pulumi/... defaults.

Mechanics

Same as pulumi-unleash: create the empty pulumiverse/pulumi-devin and I will push into it, doing
the hagaym1 to pulumiverse module-path rewrite as part of the move. No import: true needed on
this entry. Say the word if you would rather I transfer the existing repo instead.

On maintenance

Yes, I am signing up to maintain it.

Two ceilings worth flagging here rather than having them discovered later, both covered in more detail
in the issue:

  1. No live test coverage, and no path to it that I can see. Every Devin API call needs an
    enterprise or organization service-user token, and most resources mutate real enterprise
    configuration. There is no free-tier or containerized Devin to point a throwaway stack at, so
    unlike pulumi-unleash, where ApiToken runs against an OSS container, nothing here runs live.
    Coverage is compile plus schema generation, guarded by a committed schema baseline.

  2. The upstream provider constructor is reached through a shim in my repo, not upstream's. Its
    provider.New lives in internal/provider. I have a PR open upstream to export it
    (feat: add shim package re-exporting the provider constructor CognitionAI/terraform-provider-devin#3); until it lands, a local module declares a path nested
    under upstream's so Go's internal-visibility check passes. It compiles today and dropping it later
    is a go.mod-only change, but it does mean the repo claims a module path in someone else's
    namespace. Flagging in case that is a blocker.

Upstream is also pre-1.0 and moving quickly, so the provider tracks a 0.x line rather than promising
Go module stability on top of a v0 dependency.

@pulumi

pulumi Bot commented Aug 18, 2026

Copy link
Copy Markdown

🤖 Pulumi Neo didn't review this pull request: its author's GitHub account isn't connected to a Pulumi user in this repository's Pulumi organization. Agentic reviews run as the Pulumi user behind the author, so without that link Neo can't tell who to run as.

Connect your GitHub account under Pulumi Cloud account settings, signed in as a member of the organization, and Neo will review your next pull request.

@hagaym1

hagaym1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Heads up that the red Preview changes here is the fork-PR guard step, not this PR's YAML, and that
the earlier green run on this same PR did not actually preview the change. Both are worth knowing
before anyone reads the check as a verdict.

Run 1 (PR opened, 32111237685):
github.event.pull_request.merge_commit_sha was still null when the event fired, so the checkout fell
back to the base branch:

git -c protocol.version=2 fetch --no-tags --prune --depth=1 origin +b119ed6...:refs/remotes/origin/main
git checkout --progress --force -B main refs/remotes/origin/main

The guard then diffed main against main, found nothing, and passed; the preview reported
363 unchanged. So that green tick was previewing main, without this PR's two files.

Run 2 (after I force-pushed the same tree to get a fresh event,
32111524906): the merge commit
existed this time and was checked out, so the guard finally ran against the PR:

git -c protocol.version=2 fetch --no-tags --prune --depth=1 origin 28cc563...
git checkout --progress --force 28cc563...
...
fatal: origin/main...HEAD: no merge base

actions/checkout defaults to fetch-depth: 1, so the merge commit is a shallow root, and the guard's
own git fetch origin main --depth=1 produces a second, disjoint shallow history. Three-dot
origin/main...HEAD needs a merge base, and there is none.

This looks like it has simply never been exercised before: allow-unsafe-pr-checkout: true and the
guard both arrived together in 2cb3655 (2026-08-03), and the previous fork PR of this shape (#542,
2026-08-01) failed earlier in the chain, on checkout refusing fork code under pull_request_target.

Two one-line options, whichever you prefer:

  • git diff --name-only origin/main HEAD (two dots) compares trees and needs no merge base, so it is
    shallow-safe. For a "which files did this PR touch" guard against the merge commit, that is arguably
    the more accurate comparison anyway.
  • or fetch-depth: 0 on the pull_request_target checkout step.

Happy to open a separate PR for that if useful, though the guard itself forbids a fork PR from touching
.github/, so it would need to come from someone with a branch in this repo.

Since neither run validated the files, I checked them locally through this repo's own loader rather
than by eye: readAndParseFilesInFolder with the Repository and Member runtypes over both folders
passes for all 46 repositories and 47 members, with pulumi-devin resolving to
{"name":"pulumi-devin","description":"Pulumi provider for Devin","type":"provider","workflows":"ci-mgmt"}
and hagaym1.admin to ["pulumi-unleash","pulumi-devin"].

@hagaym1

hagaym1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Correcting one thing I got wrong above: I said the fix would have to come from someone with a branch in
this repo because the guard forbids a fork PR from touching .github/. That is not right.

The guard step is gated on github.event_name == 'pull_request_target', and pull_request_target only
fires for 01-teams/**, 02-repositories/** and 03-members/**. A PR that touches only
.github/workflows/pull-request.yml therefore matches the plain pull_request trigger instead (it is
not in that trigger's paths-ignore), takes the first checkout step, and never reaches the guard. So a
fork PR can carry the fix. Its own run would still fail at pulumi/actions, since a fork
pull_request gets no PULUMI_ACCESS_TOKEN or ADMIN_GITHUB_TOKEN, but that is inherent to fork PRs
here rather than the guard rejecting it.

One property worth stating explicitly, since this is a security guard rather than a convenience check:
two-dot git diff --name-only origin/main HEAD fails closed. It compares the base tip against the
merge commit, so if main has advanced with unrelated commits those files also show up as changed, and
the guard rejects the PR. That is a false positive in the safe direction. fetch-depth: 0 plus the
existing three-dot form is the more precise option if you would rather not trade that off.

Offer stands either way, and it is equally easy for one of you to apply directly.

@hagaym1

hagaym1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Opened #560 with the fix, since the guard's failure here is
not about this PR's contents.

It takes the real-history route rather than the two-dot one, so the three-dot semantics stay intact,
and it also refuses an empty merge_commit_sha instead of silently checking out the base branch, which
is what made this PR's first run green. Both behaviours are reproduced from the command line in that
PR's description.

#560 does not need to land before this one. It only changes what the check reports.

@tmeckel tmeckel self-assigned this Aug 18, 2026
@hagaym1

hagaym1 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Short version for whoever picks this up, since my earlier comments were long and the red check is noise:

Nothing is pending on me. Default unless you say otherwise: create the empty
pulumiverse/pulumi-devin, and I push, doing the hagaym1 to pulumiverse module-path and
package-name rewrite in that same push. My earlier notes about transfer-vs-empty, the upstream shim and
the missing live tests were context for the adoption decision, not open questions blocking a merge.

@hagaym1

hagaym1 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

One update, on the caveat I flagged as the most likely blocker. "Compile and schema generation only" is
now out of date: the provider has credential-free test coverage running in CI.

TestBasicTs and TestBasicPy plan a Playbook with SkipUpdate, so the programs are previewed and
never applied. That exercises the built provider binary loading and serving, the generated schema being
consumable by the CLI, each SDK constructing a resource, and provider configuration resolving from
DEVIN_TOKEN / DEVIN_API_URL. That last part is hand-written mapping in resources.go rather than
generated code, so it is the piece actually worth a test. Deleting the token from the test environment
makes both fail with Missing token, so they assert configuration rather than only that nothing
crashed. The token is fake and the API base URL is a closed port, so if a change ever makes these reach
the network they fail instead of touching a real account.

Worth noting the examples had to stop reading the getRoles data source to make this possible: a data
source is invoked during preview and does call the API, so it cannot be exercised without real
credentials. A resource create plans without one.

Both pass here: https://github.com/hagaym1/pulumi-devin/actions/runs/32263259824 - that run's overall
status is red, but only from publish_sdk, which needs org registry tokens. All four test jobs, plus
lint, License Check and prerequisites, are green.

What has not changed: there is still no create/update/delete coverage against a real account, and I
still see no realistic path to one, so that half of the caveat stands.

This PR itself is untouched, still the same two YAML files.

@tmeckel

tmeckel commented Aug 24, 2026

Copy link
Copy Markdown
Member

@hagaym1 please rebase to current main (HEAD), so that your PR picks-up the fixes from #560

@hagaym1
hagaym1 force-pushed the feat/add-pulumi-devin branch from aa75979 to 333ec03 Compare August 24, 2026 09:00
@hagaym1

hagaym1 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (a9e1bbd), so this now carries the #560 fixes. Thanks for merging that,
and for replacing my fail-fast guard with the polling waiter - that is the better shape, since it waits
for GitHub rather than making someone re-run the job.

Preview changes is green for the first time on this PR, and it actually previewed the change rather
than the base branch:

Merge commit ready: be74af5e360b912a4f8da2ee92db059b93274180
...
 +  pulumiverse:github:ProviderRepository pulumi-devin create
 +  github:index:Repository pulumi-devin create
 +  github:index:RepositoryCollaborator pulumi-devin_hagaym1 create
Resources:
    + 10 to create
    363 unchanged

Diff is unchanged, still just the two YAML files. I also re-validated both through this repo's own
configLoader with the Repository and Member runtypes after the rebase: 46 repositories and 47
members parse, pulumi-devin resolves as expected and hagaym1.admin is
["pulumi-unleash","pulumi-devin"].

@tmeckel
tmeckel added this pull request to the merge queue Aug 24, 2026
Merged via the queue into pulumiverse:main with commit b94878c Aug 24, 2026
1 check passed
@hagaym1
hagaym1 deleted the feat/add-pulumi-devin branch August 24, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants