Skip to content

Conversation

@janbuchar
Copy link
Contributor

@janbuchar janbuchar commented Oct 21, 2025

This is the first one in a series of PRs to set up OIDC based publishing to npm. It deserves special attention because it will shape the way how we approach this for the rest of the packages.

The Challenge

npm only allows configuring one workflow as the trusted publisher. That's it. But our repositories currently use two workflow files, one for pre-releases and one for stable ones.

Selected solution

I simply merged the two workflows in a single file, almost as if they were still separate. Both branches depend on a determine_path job that analyzes the event that triggered the workflow. From that point, the execution paths are completely disjoint.

This has a major advantage - both the review of the changes and of the workflow are fairly straightforward. Experience suggests that attempting to "DRY this up" makes the resulting workflow shorter, but very hard to follow.

Alternatives

  1. the DRY approach where we try to branch as deep in the workflow as possible
    • not very practical (see reasoning above)
  2. making a separate workflow just for NPM publishing and triggering it via Github API (because calling a reusable workflow won't pass the npm trusted publisher check)
    • this would require some non-trivial scripting, but it seems feasible
    • I'm unsure what the resulting workflow visualization would look like - it could be a mess
    • but we could keep the two separate workflows
    • see ci: Set up OIDC npm publishing #770
  3. abandon this and automate token rotation instead 🙈
  4. publish to npm in a separate workflow triggered each time a tag is pushed (we'd have to start making beta tags again)

@janbuchar janbuchar added the t-tooling Issues with this label are in the ownership of the tooling team. label Oct 21, 2025
@github-actions github-actions bot added this to the 126th sprint - Tooling team milestone Oct 21, 2025
@vladfrangu
Copy link
Member

Random question while I am omw home to review proper: couldn't we use composite actions for the release flows? That is, we define the steps as composite actions and then based on input run the pre release or non pre release flow 👀

Not sure if it even works but 🤷‍♂️ thought I'd throw that into the bowl

elif [[ "${{ github.event_name }}" == "push" ]] && \
[[ ! "${{ github.event.head_commit.message }}" =~ ^docs ]] && \
[[ ! "${{ github.event.head_commit.message }}" =~ ^ci ]] && \
[[ "${{ github.repository }}" =~ ^apify/ ]]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the checks for repository out into each job instead

@B4nan
Copy link
Member

B4nan commented Oct 21, 2025

Experience suggests that attempting to "DRY this up" makes the resulting workflow shorter, but very hard to follow.

Coincidentally, I just finished this monstrosity: apify/apify-docs#2032

Which goes in the very same direction, a lot of duplicity, but also a lot of "simplicity".

@janbuchar
Copy link
Contributor Author

Random question while I am omw home to review proper: couldn't we use composite actions for the release flows? That is, we define the steps as composite actions and then based on input run the pre release or non pre release flow 👀

Not sure if it even works but 🤷‍♂️ thought I'd throw that into the bowl

As long as there is only one workflow that calls npm publish (directly or via composite actions or reusable workflows), it would work. But I'm not sure if I understand the benefit - care to elaborate? It looks to me like the same thing but in multiple files

Copy link
Member

@B4nan B4nan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, not great, not terrible. i'll surely prefer readability over deduplication.

sidenote: i am quite sure that after we finish migration in the last repo, they will allow whitelisting multiple workflows :trollface:

@janbuchar
Copy link
Contributor Author

looks good to me, not great, not terrible. i'll surely prefer readability over deduplication.

Same here. Alternative 2 (a custom action to trigger a publishing workflow) is the only one that I'd consider more seriously. @barjin and @vladfrangu, are you OK with that?

sidenote: i am quite sure that after we finish migration in the last repo, they will allow whitelisting multiple workflows :trollface:

Right? 😁

@B4nan
Copy link
Member

B4nan commented Oct 22, 2025

Considering how many repos we will need to change, I would keep things simple.

@janbuchar
Copy link
Contributor Author

Considering how many repos we will need to change, I would keep things simple.

I'm 100% on board with that. The custom action would only have to be written once and it would probably help make diffs smaller during the migration.

@vladfrangu
Copy link
Member

That is what I was kinda hinting at with reusable actions -> we could move our release flows (if possible?) to /workflows and re-use them across repos... But I am not as up to date with our release pipeline to know if thats feasible enough :D

@B4nan
Copy link
Member

B4nan commented Oct 22, 2025

I'll leave this up to you guys, if we can make it simpler than this without much effort, I'm all in for that, but if it would mean more than a day of work, it doesn't seem worth it.

Copy link
Contributor

@barjin barjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @janbuchar, this looks good to me.

The current solution is imo perfectly sufficient, I agree that deduplicating this would likely result in hard-to-read bash/yaml ternary exprs.

# ROUTE DECISION
# ============================================================================

determine_path:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe (determine|pick)_release_type would fit this job better. At first, I thought "release path" would be a filesystem path with the build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, and i also like pick better than determine

@janbuchar
Copy link
Contributor Author

After an internal discussion, we decided to go with the alternative approach (custom action that triggers a separate workflow).

@janbuchar janbuchar closed this Oct 24, 2025
@janbuchar janbuchar changed the title ci: Set up OIDC NPM publishing ci: Set up OIDC NPM publishing (initial attempt) Oct 24, 2025
janbuchar added a commit that referenced this pull request Oct 24, 2025
- closes #732
- see discussion in #768
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set up OIDC npm publishing

5 participants