Github Actions have me as CONTRIBUTOR role when I'm OWNER

I’m using an Action that should only run for repo owners:

name: "Comment run"
on:
  issue_comment:
    types: [created, edited]

jobs:
  comment-run:
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@v2
      with:
        # 0 indicates all history
        fetch-depth: 0
    - uses: nwtgck/actions-comment-run@v1.1.3
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        allowed-associations: '["OWNER"]'

When I run it, I get the following in the Action logs:

Run nwtgck/actions-comment-run@v1.1.3
  with:
    github-token: ***
    allowed-associations: ["OWNER"]
NOTE: The allowed associations to run scripts are ["OWNER"], but you are CONTRIBUTOR.

even though I’m definitely an owner of the org:

It almost seems like Github is incorrectly choosing the role CONTRIBUTOR even though I should have OWNER.

The comment I used to trigger the run, if it’s helpful:

@github-actions run

<details>
<summary>🚀 Merge preview</summary>

\`\`\`js
(async () => {
  // Get pull-req URL like "https://api.github.com/repos/nwtgck/actions-merge-preview/pulls/4"
  const pullReqUrl = context.payload.issue.pull_request.url;
  const githubUser = context.payload.repository.owner.login;
  const res = await fetch(pullReqUrl, {
    headers: [
      ['Authorization', `Basic ${Buffer.from(`${githubUser}:${githubToken}`).toString('base64')}`]
    ]
  });
  const resJson = await res.json();
  const prUserName = resJson.head.user.login;
  const baseBranchName = resJson.base.ref;
  const branchName = resJson.head.ref;
  const fullRepoName = resJson.head.repo.full_name;
  const previewBranchName = `actions-merge-preview/${prUserName}-${branchName}`;
  execSync(`git config --global user.email "github-actions[bot]@users.noreply.github.com"`);
  execSync(`git config --global user.name "github-actions[bot]"`);
  // (from: https://stackoverflow.com/a/23987039/2885946)
  execSync(`git fetch --all`);
  console.log(execSync(`git checkout ${baseBranchName}`).toString());
  console.log(execSync(`git checkout -b ${previewBranchName} ${baseBranchName}`).toString());
  console.log(execSync(`git pull https://github.com/${fullRepoName}.git ${branchName}`).toString());
  // Push preview branch
  // NOTE: Force push (should be safe because preview branch always start with "actions-merge-preview/")
  execSync(`git push -fu origin ${previewBranchName}`);
  const baseRepoFullName = context.payload.repository.full_name;
  // Create GitHub client
  const githubClient = new GitHub(githubToken);
  // Comment body
  const commentBody = `🚀 Preview branch:  \n<https://github.com/${baseRepoFullName}/tree/${previewBranchName}>`;
  // Comment the deploy URL
  await postComment(commentBody);
})();
\`\`\`
</details>
1 Like

@nwtgck for SA, if you happen to know what’s going on here

Thanks for flagging @valenchak ! Would this cause the issue I’m seeing though? I first saw this 12h ago, so maybe before the degradation happened

@mieubrisse,

According to my tests, I found some amazing things, I think these can explain the problem you are facing:

  1. In my user repository (e.g. BrightRan/MyRepo):

    • When I add comments to the issue or PR in this repository, the value of “github.event.comment.author_association” is “OWNER”.

    • When another user who is the Collaborator of this repository adds comments in this repository, the value of “github.event.comment.author_association” is “COLLABORATOR”.

    • When another user who is not the Collaborator of this repository adds comments in this repository, the value of “github.event.comment.author_association” is “CONTRIBUTOR”.

  2. In my organization repository (e.g. myOrg/MyRepo):
    I’m the default first Owner of the organization, both the organization and the repository in this organization were created by me.

    • If I do not add myself as the Collaborator of this repository, when I add comments in this repository, the value of “github.event.comment.author_association” is “CONTRIBUTOR”.

    • If I add myself as the Collaborator of this repository, when I add comments in this repository, the value of “github.event.comment.author_association” is “COLLABORATOR”.

    • When another user who is the Collaborator of this repository adds comments in this repository, the value of “github.event.comment.author_association” is “COLLABORATOR”. Even if he has obtained the Owner role of the organization.

    • When another user who is not the Collaborator of this repository adds comments in this repository, the value of “github.event.comment.author_association” is “NONE”. Even if he has obtained the Owner role of the organization.

1 Like

Wow, thanks for checking on this @brightran - that’s very strange that the only time when OWNER is assigned is a personal repo! This is definitely a code bug, right? I’m looking at CommentAuthorAssociation and both CONTRIBUTOR and COLLABORATOR are so broad I don’t think I could use them for running arbitrary Github Actions code.

@mieubrisse,

This is definitely a code bug, right?

Not sure if this is a bug.

During my tests, I found that each repository seems has only one owner:

  • The owner of the user repository is the login name of the authenticated user. For example, BrightRan is the only owner of the repository BrightRan/MyRepo.

  • The owner of the organization repository is the name of the organization. For example, myOrg is the only owner of the repository myOrg/MyRepo. The users who are the “Owner” role in the organization are not the common owners of the repository. This is indeed puzzling.

Maybe you can contact GitHub Support to get more help.

Thanks for the pointer, @brightran ! Unfortunately, that contact link seems to have been revamped and there’s no way to file bug reports there - they simply direct back to these forums. Other users are struggling with the same thing so hopefully the staff investigate this post.

Summary for anyone starting the thread from here: when repos are owned by an organization and the members of the org who are listed as “Owner” post a comment, the ownership of those comments doesn’t receive the OWNER association from CommentAuthorAssociation enum. AFAICT this is a bug in Github itself.

1 Like

I’ve gotten in touch with the Github team (support ticket no. 884535) and James has confirmed that this is a bug with Github Actions. There’s no ETA on a fix, however.

2 Likes

We have a very similar use case. We have a job that we want to trigger based on a comment in a PR. As the job requires access to secrets, we need to restrict the ability to trigger it to people that have commit access to the repository.

I had hoped something like this would be sufficient:

if: |
  github.event.issue.pull_request && startsWith(github.event.comment.body, '!deploy') && (
    github.event.comment.author_association == 'OWNER' ||
    github.event.comment.author_association == 'MEMBER' ||
    github.event.comment.author_association == 'COLLABORATOR'
  )

As part of a large org, we manage repository access by teams. When a member of a team that has the Admin role for this repository comments on a PR, they have the CONTRIBUTOR author association. I had expected MEMBER.

Any updates here? Anyone have other approaches to this use case?

Thanks for the workaround! I have a Organization project that used

    if: ${{ github.actor.login == github.event.repository.owner.login }}

It was work, but now It’s not working anymore, not sure when It’s not working since the project had not updated over a half year.

Just here to confirm this bug wasn’t a bug before.

I have the same issue, we have a member in our organisation, however the GitHub author_association says they are a contributor.

I.e. when I print out the GitHub context, I get:

However, they are definitely a member:

IMO, MEMBER should trump CONTRIBUTOR?

We asked GitHub support about this and for us at least, the problem was casued by not being a visible member of the organisation

Changing that to public fixed it for us (CONTRIBUTOR vs MEMBER, but likely applies to OWNER too)

1 Like

I wanted to follow up on my previous comment with the solution that we ended up using. Rather than relaying on attributes of the event, we hit the API using actions/github-script:

- name: isOrgMember?
  id: is-org-member
  uses: actions/github-script@v3
  with:
    result-encoding: string
    script: |
      const organization = 'ourorg';
      const user = "${{ github.event.comment.user.login }}";
      try {
          org = await github.orgs.checkMembershipForUser({
              org: organization,
              username: user,
          });
          console.log(`${org.headers.status}: ${user} found in ${organization}`);
          return 'true';
      } catch(err) {
          console.log(`${err.headers.status}: ${user} not found in ${organization}`);
          return 'false';
      };

According to the docs, this will:

Check if a user is, publicly or privately, a member of the organization.

See: Organizations - GitHub Docs

The subsequent steps check the output like:

- name: Do the thing
  if: steps.is-org-member.outputs.result == 'true'
  run: make thing
1 Like

I can confirm that setting membership to public fixed this for members of our org also…

1 Like