Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# @changesets/action

## 1.8.2

### Patch Changes

- [`e47dcdc`](https://github.com/changesets/action/commit/e47dcdcda2d3c570ab43fc31f1ac43872b47a5a4) Thanks [@openscript](https://github.com/openscript)! - Filter clientside for Forgejo

## 1.8.1

### Patch Changes

- [`2135466`](https://github.com/changesets/action/commit/213546601666ba543dd4a716db7b148c55f4c36f) Thanks [@openscript](https://github.com/openscript)! - Encode branch and base

## 1.8.0

### Minor Changes
Expand All @@ -11,6 +23,7 @@
- [#502](https://github.com/changesets/action/pull/502) [`6002dbd`](https://github.com/changesets/action/commit/6002dbd987f49a3c0a134910d9c7bca975b79977) Thanks [@oshytiko](https://github.com/oshytiko)! - Fixed initial `.changeset` state being picked up, when `cwd` parameter is provided

- [#536](https://github.com/changesets/action/pull/536) [`81b3f61`](https://github.com/changesets/action/commit/81b3f61ebffcb868f73e4c0b2682517149c834a2) Thanks [@radnan](https://github.com/radnan)! - Fixed `.changeset` state being picked for the version command when `cwd` parameter is provided
- [`905ea6d`](https://github.com/changesets/action/commit/905ea6d481f54d210f11da2daa15655dadd89f15) Thanks [@openscript](https://github.com/openscript)! - Add Forgejo/Gitea actions support

## 1.7.0

Expand Down
22 changes: 21 additions & 1 deletion src/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createFixture } from "fs-fixture";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { Git } from "./git.ts";
import { setupOctokit } from "./octokit.ts";
import { runVersion } from "./run.ts";
import { isForgejoOrGitea, runVersion } from "./run.ts";

vi.mock("@actions/github", () => ({
context: {
Expand Down Expand Up @@ -427,3 +427,23 @@ fluminis divesque vulnere aquis parce lapsis rabie si visa fulmineis.
expect(mockedGraphql.mock.calls[0]).toMatchSnapshot();
});
});

describe("isForgejoOrGitea", () => {
it("returns false when no Forgejo/Gitea env vars are set", () => {
delete process.env.GITEA_ACTIONS;
delete process.env.FORGEJO_ACTIONS;
expect(isForgejoOrGitea()).toBe(false);
});

it("returns true when GITEA_ACTIONS is set", () => {
process.env.GITEA_ACTIONS = "true";
expect(isForgejoOrGitea()).toBe(true);
delete process.env.GITEA_ACTIONS;
});

it("returns true when FORGEJO_ACTIONS is set", () => {
process.env.FORGEJO_ACTIONS = "true";
expect(isForgejoOrGitea()).toBe(true);
delete process.env.FORGEJO_ACTIONS;
});
});
105 changes: 83 additions & 22 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,69 @@ import {

const require = createRequire(import.meta.url);

/**
* Detects if we're running on Forgejo or Gitea Actions.
* These platforms set specific environment variables when running actions.
*/
export function isForgejoOrGitea(): boolean {
return !!(process.env.GITEA_ACTIONS || process.env.FORGEJO_ACTIONS);
}

type PullRequestData = {
number: number;
title: string;
body: string | null;
state: string;
head?: { ref: string };
base?: { ref: string };
};

/**
* Fetches existing pull requests from the version branch to the base branch.
* Uses different API endpoints for GitHub vs Forgejo/Gitea.
*
* GitHub: GET /repos/{owner}/{repo}/pulls?state=open&head={owner}:{branch}&base={base}
* Forgejo/Gitea: List all open PRs and filter client-side (their list API doesn't support head/base filters)
*/
export async function getExistingPullRequests(
octokit: Octokit,
options: {
owner: string;
repo: string;
head: string;
base: string;
}
): Promise<PullRequestData[]> {
if (isForgejoOrGitea()) {
core.info("Detected Forgejo/Gitea environment, using compatible API");
// Forgejo/Gitea list endpoint doesn't support head/base filters,
// so we list all open PRs and filter client-side
const response = await octokit.rest.pulls.list({
owner: options.owner,
repo: options.repo,
state: "open",
});
// Filter by head and base branch
const filtered = response.data.filter(
(pr) => pr.head.ref === options.head && pr.base.ref === options.base
);
core.info(
`Found ${response.data.length} open PR(s), ${filtered.length} matching head=${options.head} base=${options.base}`
);
return filtered;
} else {
// GitHub API: GET /repos/{owner}/{repo}/pulls with query params
const response = await octokit.rest.pulls.list({
owner: options.owner,
repo: options.repo,
state: "open",
head: `${options.owner}:${options.head}`,
base: options.base,
});
return response.data;
}
}

// GitHub Issues/PRs messages have a max size limit on the
// message body payload.
// `body is too long (maximum is 65536 characters)`.
Expand Down Expand Up @@ -71,12 +134,12 @@ type PublishedPackage = { name: string; version: string };

type PublishResult =
| {
published: true;
publishedPackages: PublishedPackage[];
}
published: true;
publishedPackages: PublishedPackage[];
}
| {
published: false;
};
published: false;
};

export async function runPublish({
script,
Expand Down Expand Up @@ -108,7 +171,7 @@ export async function runPublish({
if (pkg === undefined) {
throw new Error(
`Package "${pkgName}" not found.` +
"This is probably a bug in the action, please open an issue",
"This is probably a bug in the action, please open an issue",
);
}
releasedPackages.push(pkg);
Expand All @@ -127,7 +190,7 @@ export async function runPublish({
if (packages.length === 0) {
throw new Error(
`No package found.` +
"This is probably a bug in the action, please open an issue",
"This is probably a bug in the action, please open an issue",
);
}
let pkg = packages[0];
Expand Down Expand Up @@ -199,11 +262,10 @@ export async function getVersionPrBody({
prBodyMaxCharacters,
branch,
}: GetMessageOptions) {
let messageHeader = `This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and ${
hasPublishScript
? `the packages will be published to npm automatically`
: `publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)`
}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${branch}, this PR will be updated.
let messageHeader = `This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and ${hasPublishScript
? `the packages will be published to npm automatically`
: `publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)`
}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${branch}, this PR will be updated.
`;
let messagePrestate = !!preState
? `⚠️⚠️⚠️⚠️⚠️⚠️
Expand Down Expand Up @@ -330,9 +392,8 @@ export async function runVersion({
);

const finalPrTitle = `${prTitle}${!!preState ? ` (${preState.tag})` : ""}`;
const finalCommitMessage = `${commitMessage}${
!!preState ? ` (${preState.tag})` : ""
}`;
const finalCommitMessage = `${commitMessage}${!!preState ? ` (${preState.tag})` : ""
}`;

/**
* Fetch any existing pull requests that are open against the branch,
Expand All @@ -341,15 +402,15 @@ export async function runVersion({
* (`@changesets/ghcommit` has to reset the branch to the same commit as the base,
* which GitHub will then react to by closing the PRs)
*/
const existingPullRequests = await octokit.rest.pulls.list({
...github.context.repo,
state: "open",
head: `${github.context.repo.owner}:${versionBranch}`,
const existingPullRequests = await getExistingPullRequests(octokit, {
owner: github.context.repo.owner,
repo: github.context.repo.repo,
head: versionBranch,
base: branch,
});
core.info(
`Existing pull requests: ${JSON.stringify(
existingPullRequests.data,
existingPullRequests,
null,
2,
)}`,
Expand All @@ -369,7 +430,7 @@ export async function runVersion({
prBodyMaxCharacters,
});

if (existingPullRequests.data.length === 0) {
if (existingPullRequests.length === 0) {
core.info("creating pull request");
const { data: newPullRequest } = await octokit.rest.pulls.create({
base: branch,
Expand All @@ -384,7 +445,7 @@ export async function runVersion({
pullRequestNumber: newPullRequest.number,
};
} else {
const [pullRequest] = existingPullRequests.data;
const [pullRequest] = existingPullRequests;

core.info(`updating found pull request #${pullRequest.number}`);
const convertPullRequestToDraftMutation =
Expand Down