Skip to content

The create-github-release.yml workflow fails #928

@kabir

Description

@kabir

When releasing 1.0.0.Final the job failed https://github.com/a2aproject/a2a-java/actions/runs/27285972511/job/80593190218

CoPilot says:

The failure is caused by missing authentication for the GitHub API calls in the workflow.

Root cause

The job fails with:

  • Unhandled error: HttpError: Requires authentication - https://docs.github.com/rest

The failing calls are in the workflow itself:

  • release note tag lookup at .github/workflows/create-github-release.yml:40
  • release creation at .github/workflows/create-github-release.yml:103

Workflow file:

Why it fails

Both actions/github-script@v9 steps use github.rest.*, but the workflow does not pass a token into those steps. Even though the job declares:

permissions:
  contents: write

that only scopes the GITHUB_TOKEN; it does not automatically inject it into every script context for this action usage. The scripts need an authenticated token.

Fix

Pass ${{ secrets.GITHUB_TOKEN }} to both actions/github-script steps.

Suggested patch

Update .github/workflows/create-github-release.yml like this:

- name: Generate release notes
  id: release_notes
  uses: actions/github-script@v9
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      const version = '${{ steps.version.outputs.version }}';

      // Get the previous tag
      let previousTag = '';
      try {
        const { data: tags } = await github.rest.repos.listTags({
          owner: context.repo.owner,
          repo: context.repo.repo,
          per_page: 100
        });

        const currentIndex = tags.findIndex(tag => tag.name === context.ref.replace('refs/tags/', ''));

        if (currentIndex >= 0 && currentIndex < tags.length - 1) {
          previousTag = tags[currentIndex + 1].name;
        }
      } catch (error) {
        console.log('Could not fetch previous tag:', error.message);
      }

      let releaseNotes = `## A2A Java SDK ${version}\n\n`;
      return releaseNotes;

- name: Create GitHub Release
  uses: actions/github-script@v9
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      const version = '${{ steps.version.outputs.version }}';
      const tag = context.ref.replace('refs/tags/', '');
      const releaseNotes = ${{ steps.release_notes.outputs.result }};

      const isPrerelease = version.includes('Alpha') ||
                          version.includes('Beta') ||
                          version.includes('RC') ||
                          version.includes('SNAPSHOT');

      try {
        const { data: release } = await github.rest.repos.createRelease({
          owner: context.repo.owner,
          repo: context.repo.repo,
          tag_name: tag,
          name: `v${version}`,
          body: releaseNotes,
          draft: false,
          prerelease: isPrerelease,
          generate_release_notes: true
        });

        console.log(`✅ Created release: ${release.html_url}`);
        core.summary
          .addHeading(`Release v${version} Created`)
          .addLink('View Release', release.html_url)
          .addLink('Maven Central', `https://central.sonatype.com/artifact/org.a2aproject.sdk/a2a-java-sdk-parent/${version}`)
          .write();

      } catch (error) {
        if (error.status === 422 && error.message.includes('already_exists')) {
          console.log('⚠️  Release already exists for this tag');
        } else {
          throw error;
        }
      }

Minimal diff

       - name: Generate release notes
         id: release_notes
         uses: actions/github-script@v9
         with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
           script: |

       - name: Create GitHub Release
         uses: actions/github-script@v9
         with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
           script: |

Optional hardening

To make the workflow a bit more robust, you can also use the explicit expression form:

github-token: ${{ github.token }}

Either form is acceptable in this repo context.

Summary

The solution is to authenticate both GitHub Script steps with the workflow token. The failure is not in the release logic itself; it is in the missing token wiring for the REST API calls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions