Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
94f3c7f
feat(openapi): Scalar API Reference documentation support (#7817)
soyuka Mar 5, 2026
c2909a1
fix(mcp): fallback to sdk handler when not found (#7818)
soyuka Mar 6, 2026
effc99e
Merge 4.3
soyuka Mar 20, 2026
61c6dee
Merge 4.3
soyuka Mar 25, 2026
79d31e1
Merge 4.3
soyuka Apr 27, 2026
70769a5
Merge 4.3
soyuka Apr 30, 2026
cc0ae12
feat: support dynamic HTTP response status code via request attribute…
Griffon-Weglot May 4, 2026
a47e36c
fix(state): scope ReadLinkParameterProvider to current Link's class (…
soyuka May 4, 2026
5ca0b57
test: phpunit exception not restored (#7949)
soyuka May 5, 2026
73098ec
Merge 4.3
soyuka May 6, 2026
72b02af
feat(hydra): use hydra:memberAssertion instead of owl:equivalentClass…
abderrahimghazali May 6, 2026
7d6b830
Merge 4.3
soyuka May 6, 2026
217803d
refactor(jsonld): simplify @context building (#7952)
soyuka May 7, 2026
d57200a
Merge 4.3
soyuka May 7, 2026
d36c14c
refactor: split normalizer/denormalizer (#7713)
soyuka May 7, 2026
406ae36
Merge 4.3
soyuka May 11, 2026
1d7695d
test(jsonld,hydra,hal): migrate behat features to ApiTestCase (#7957)
soyuka May 11, 2026
9df6518
Merge 4.3
soyuka May 13, 2026
5a2afb1
Merge 4.3
soyuka May 18, 2026
98dc77b
feat(doctrine): state options repositoryMethod for query builder (#7115)
soyuka May 21, 2026
2ff386b
feat(symfony,laravel): `withCredentials` option to Swagger UI (#8197)
cay89 May 22, 2026
e4684ef
test: migrate remaining trivial behat features to ApiTestCase (#7971)
soyuka May 22, 2026
7383ea7
Merge 4.3
soyuka May 22, 2026
e6922f1
test: eliminate behat-migration skips and tighten ported asserts (#8198)
soyuka May 26, 2026
d44867d
test: migrate elasticsearch/security/serializer/mongodb behat suites …
soyuka May 28, 2026
d371f65
chore: drop ad-hoc mongodb deps and the throwaway scaffolder
soyuka May 28, 2026
d219071
Merge 4.3
soyuka May 28, 2026
5ddf94a
feat(jsonld): add resource-level jsonldContext for namespace prefixes…
soyuka May 28, 2026
c2b990e
ci: stale bot via actions to use typed issues (#8208)
soyuka May 29, 2026
67b1c51
ci(stale): bump checkout to v6 and github-script to v8 (#8213)
soyuka May 29, 2026
374c61d
Merge 4.3
soyuka May 29, 2026
4911cfd
test: migrate doctrine/graphql behat features to ApiTestCase (#8205)
soyuka May 29, 2026
34e46af
ci: trim phpunit-components matrix and merge fail-deprecation (#8214)
soyuka May 30, 2026
b2f1a5a
feat(metadata): throwOnNotFound option (#6027)
soyuka Jun 1, 2026
3c658d1
feat!(state): constraint-aware 422 for denormalization errors (#8211)
soyuka Jun 2, 2026
9179b36
feat(doctrine): per-property filter map in FreeTextQueryFilter (#8257)
soyuka Jun 8, 2026
33210c6
Merge 4.3 to main
soyuka Jun 8, 2026
e62e42f
chore: fix php-cs-fixer (#8269)
alexisLefebvre Jun 10, 2026
573df71
test: drop stale serializer 8.1 getErrors() deprecation expectation (…
soyuka Jun 13, 2026
6cac23a
Merge 4.3
soyuka Jun 16, 2026
2b5031d
Merge 4.3
soyuka Jun 17, 2026
b0f6dbd
feat(doctrine): add EndSearchFilter primary for ORM and ODM (#8319)
soyuka Jun 17, 2026
517f697
Merge 4.3
soyuka Jun 17, 2026
af0a0ab
feat(doctrine): promote ComparisonFilter out of @experimental (#8323)
soyuka Jun 17, 2026
6942dc0
feat(doctrine): promote OrFilter out of @experimental (#8324)
soyuka Jun 17, 2026
48bc56e
feat(metadata): document BackwardCompatibleFilterDescriptionTrait as …
soyuka Jun 17, 2026
4bf850f
feat(doctrine): add StartSearchFilter and WordStartSearchFilter (ORM …
soyuka Jun 17, 2026
c3fd6dd
feat(doctrine): deprecate AbstractFilter base class (#8330)
soyuka Jun 17, 2026
c9e5071
feat(symfony): deprecate Symfony Security AccessDeniedException (#8318)
soyuka Jun 17, 2026
8f48b9d
feat(symfony): deprecate jsonapi.use_iri_as_id defaulting to true (#8…
soyuka Jun 22, 2026
373b56b
feat(doctrine): deprecate the extends-AbstractFilter form of Date/Ran…
soyuka Jun 22, 2026
9b1a58f
feat(doctrine): deprecate the legacy SearchFilter/Boolean/Numeric/Bac…
soyuka Jun 22, 2026
3caae14
Merge 4.3
soyuka Jun 23, 2026
9b7ace5
fix(graphql): build filter args from parameters (#8347)
soyuka Jun 23, 2026
75f9056
feat(openapi): support OpenAPI 3.2.0 (#8350)
soyuka Jun 25, 2026
0fb1dc8
feat(symfony): api:upgrade-filter codemod + filter fixture migration …
soyuka Jun 25, 2026
5b5d16d
Merge remote-tracking branch 'upstream/4.3'
soyuka Jun 25, 2026
22ece51
chore: open 5.0 development line
soyuka Jun 25, 2026
06a3b72
ci: set COMPOSER_ROOT_VERSION to 4.4.x-dev
soyuka Jun 25, 2026
3cdbaf4
doc: changelog 4.4.0-alpha.1
soyuka Jun 25, 2026
b3f02f4
chore: require ^4.4@alpha for inter-package dependencies
soyuka Jun 25, 2026
ee81a5d
test(serializer): skip union-collection IRI test on legacy property-i…
soyuka Jun 26, 2026
3096906
test(functional): skip union-collection IRI test on legacy property-i…
soyuka Jun 26, 2026
dee0df1
doc: changelog 4.4.0-alpha.2
soyuka Jun 26, 2026
03f6519
Merge branch '4.3' into 4.4
soyuka Jun 26, 2026
123160b
Merge branch '4.4'
soyuka Jun 26, 2026
63d345d
chore: bump inter-package constraints to ^5.0@alpha
soyuka Jun 29, 2026
d37a753
feat(doctrine): standalone Date/Exists filters, ComparisonFilter [bet…
soyuka Jun 29, 2026
8db71f6
chore: stabilize Elasticsearch, parameter providers and PropertyAware…
soyuka Jun 30, 2026
1e6d13a
feat!: core 5.0 cleanups (getProperties interface, json:api status st…
soyuka Jun 30, 2026
a8af988
chore(metadata): remove stale 3.0 TODO in IdentifiersExtractor (#8368)
soyuka Jun 30, 2026
4a9a145
feat!: remove legacy PropertyInfo Type system (#8364)
soyuka Jun 30, 2026
7dfba0c
docs(jsonld): drop misleading @type TODO, document intentional behavi…
soyuka Jun 30, 2026
e22e744
feat!: remove deprecated APIs scheduled for 5.0 (#8367)
soyuka Jul 1, 2026
c41505c
chore(deps): bump codecov/codecov-action from 5 to 7 (#8372)
dependabot[bot] Jul 2, 2026
7047028
chore(deps): bump actions/checkout from 6 to 7 (#8373)
dependabot[bot] Jul 2, 2026
ccf5187
chore(deps): bump actions/cache from 5 to 6 (#8375)
dependabot[bot] Jul 2, 2026
ea1f385
chore(deps): bump actions/github-script from 8 to 9 (#8374)
dependabot[bot] Jul 2, 2026
083dabe
Merge 4.3 into 4.4
soyuka Jul 12, 2026
722ed09
fix(validator): forward-port enum backing type into DenormalizationVi…
soyuka Jul 12, 2026
1cacc0b
fix(test): drop stale serializer 8.1 deprecation guard on ported enum…
soyuka Jul 12, 2026
af4e04b
Merge pull request #8396 from soyuka/mergeup-4.4-into
soyuka Jul 12, 2026
db5c7d8
chore: remove @experimental from stabilized APIs (#8398)
soyuka Jul 12, 2026
2d104d0
chore: require Symfony ^7.4 across all components (#8397)
soyuka Jul 12, 2026
432992e
Merge 4.4 into main
soyuka Jul 12, 2026
88f458a
fix(jsonschema): drop removed getBuiltinTypes path in SchemaPropertyM…
soyuka Jul 12, 2026
8360186
fix(serializer): remove dead native-type guards in AbstractItemNormal…
soyuka Jul 12, 2026
bc387cd
style: cs-fixer
soyuka Jul 12, 2026
7823146
Merge pull request #8399 from soyuka/mergeup-4.4-into-main
soyuka Jul 12, 2026
af57ec6
perf(state): skip response body on HEAD requests (#8348)
Nayte91 Jul 12, 2026
f8c2172
fix(state): correct composer "conflicts" key to "conflict" (#8400)
soyuka Jul 12, 2026
f7ee06d
Merge 4.4 into main
soyuka Jul 12, 2026
f41921b
doc: changelog 4.4.0-alpha.3
soyuka Jul 12, 2026
9941b65
Merge pull request #8401 from soyuka/mergeup-4.4-main-round2
soyuka Jul 12, 2026
1515eb7
doc: changelog 5.0.0-alpha.2
soyuka Jul 12, 2026
dd00d0f
chore: resolve stale SerializerContextBuilder / ContextAction 5.0 TOD…
soyuka Jul 20, 2026
e1c900f
chore(deps): bump actions/setup-node from 6 to 7 (#8437)
dependabot[bot] Aug 16, 2026
78151b7
fix(mcp): return resource read results for resources (#8436)
ousamabenyounes Aug 16, 2026
7085b6d
Merge branch '4.3' into 4.4
soyuka Aug 16, 2026
cf2dca9
Merge branch '4.4'
soyuka Aug 16, 2026
d3935bf
ci: restore the PMU_VERSION pin that the merge up dropped (#8474)
ousamabenyounes Sep 1, 2026
a16cb28
ci: raise inter-component floors so the PHP 8.5 lowest jobs pass (#8445)
ousamabenyounes Sep 1, 2026
20c2490
test: drop DoctrineTest methods revived by the merge
soyuka Sep 1, 2026
88e71ef
ci(jsonapi): pin the serializer floor to alpha.3
soyuka Sep 1, 2026
df9f35c
Merge branch '4.3' into 4.4
soyuka Sep 1, 2026
53793e9
Merge branch '4.4'
soyuka Sep 1, 2026
2e7aa37
Merge branch '4.3' into 4.4
soyuka Sep 1, 2026
f653607
Merge branch '4.4'
soyuka Sep 1, 2026
672d48e
feat(symfony): map UniqueConstraintViolationException to 422 by defau…
Amoifr Sep 1, 2026
854c921
fix(metadata): stop alerting on inline unwired filters at warmup (#8490)
soyuka Sep 1, 2026
56ac965
Merge branch '4.3' into 4.4
soyuka Sep 4, 2026
87dae7f
chore: bump metadata floor to alpha.4
soyuka Sep 4, 2026
c6b048a
doc: changelog 4.4.0-alpha.4
soyuka Sep 4, 2026
66545cc
Merge branch '4.4'
soyuka Sep 4, 2026
233880f
chore: bump metadata floor to 5.0.0-alpha.3
soyuka Sep 4, 2026
f631000
doc: changelog 5.0.0-alpha.3
soyuka Sep 4, 2026
74bef19
test(doctrine): adapt unwired filter test to 5.0 (#8501)
soyuka Sep 5, 2026
6ce161d
fix(mcp): declare missing dependencies and run the component in CI
Maxcastel Sep 8, 2026
ec36afa
fix(mcp): skip ToolProvider mapping when the request carries no tool …
Maxcastel Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
167 changes: 167 additions & 0 deletions .github/scripts/stale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
module.exports = async ({ github, context, core }) => {
const DAYS_UNTIL_STALE = 60;
const DAYS_UNTIL_CLOSE = 7;
const STALE_LABEL = 'stale';
const EXEMPT_LABELS = new Set([
'Hacktoberfest',
'RFC',
'⭐ EU-FOSSA Hackathon',
]);
const EXEMPT_TYPES = new Set(['Bug', 'Feature']);
const STALE_COMMENT = [
'This issue has been automatically marked as stale because it has not had',
'recent activity. It will be closed if no further activity occurs. Thank you',
'for your contributions.',
].join(' ');
const BOT_LOGINS = new Set(['github-actions[bot]', 'github-actions']);

const DRY_RUN = /^(1|true|yes)$/i.test(process.env.DRY_RUN || '');
const MAX_ACTIONS_PER_RUN = Number.parseInt(process.env.MAX_ACTIONS_PER_RUN || '25', 10);

const { owner, repo } = context.repo;
const now = Date.now();
const staleCutoff = new Date(now - DAYS_UNTIL_STALE * 86400000);
const closeCutoff = new Date(now - DAYS_UNTIL_CLOSE * 86400000);

let actionsTaken = 0;
const budgetExhausted = () => actionsTaken >= MAX_ACTIONS_PER_RUN;

async function* iterateOpenIssues() {
let cursor = null;
while (true) {
const data = await github.graphql(`
query($owner: String!, $name: String!, $cursor: String) {
repository(owner: $owner, name: $name) {
issues(first: 100, after: $cursor, states: OPEN, orderBy: {field: UPDATED_AT, direction: ASC}) {
pageInfo { hasNextPage endCursor }
nodes {
number
updatedAt
issueType { name }
labels(first: 50) { nodes { name } }
timelineItems(last: 100, itemTypes: [LABELED_EVENT]) {
nodes {
... on LabeledEvent {
createdAt
label { name }
}
}
}
}
}
}
}`, { owner, name: repo, cursor });

const page = data.repository.issues;
for (const node of page.nodes) yield node;
if (!page.pageInfo.hasNextPage) break;
cursor = page.pageInfo.endCursor;
}
}

async function hasNonBotActivitySince(issue_number, since) {
const events = await github.paginate(
github.rest.issues.listEventsForTimeline,
{ owner, repo, issue_number, per_page: 100 },
);
return events.some(e => {
const ts = e.created_at || e.submitted_at;
if (!ts) return false;
if (new Date(ts) <= since) return false;
const actor = e.actor?.login || e.user?.login;
if (actor && BOT_LOGINS.has(actor)) return false;
return true;
});
}

function mostRecentStaleAt(issue) {
let latest = null;
for (const e of issue.timelineItems.nodes) {
if (e?.label?.name !== STALE_LABEL) continue;
const at = new Date(e.createdAt);
if (!latest || at > latest) latest = at;
}
return latest;
}

async function addStale(issue_number) {
if (DRY_RUN) {
core.info(`DRY_RUN would stale #${issue_number}`);
return;
}
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [STALE_LABEL] });
await github.rest.issues.createComment({ owner, repo, issue_number, body: STALE_COMMENT });
}

async function close(issue_number) {
if (DRY_RUN) {
core.info(`DRY_RUN would close #${issue_number}`);
return;
}
await github.rest.issues.update({
owner, repo, issue_number, state: 'closed', state_reason: 'not_planned',
});
}

async function unstale(issue_number) {
if (DRY_RUN) {
core.info(`DRY_RUN would unstale #${issue_number}`);
return;
}
await github.rest.issues.removeLabel({
owner, repo, issue_number, name: STALE_LABEL,
}).catch(err => {
if (err.status !== 404) throw err;
});
}

const summary = { staled: 0, closed: 0, unstaled: 0, exempt: 0, scanned: 0, skipped: 0 };

for await (const issue of iterateOpenIssues()) {
summary.scanned++;
const labels = new Set(issue.labels.nodes.map(l => l.name));
const typeName = issue.issueType?.name;
const exempt = (typeName && EXEMPT_TYPES.has(typeName))
|| [...labels].some(l => EXEMPT_LABELS.has(l));
const hasStale = labels.has(STALE_LABEL);

if (hasStale) {
const staleAt = mostRecentStaleAt(issue);
if (!staleAt) continue;

const interacted = await hasNonBotActivitySince(issue.number, staleAt);
if (interacted) {
if (budgetExhausted()) { summary.skipped++; continue; }
await unstale(issue.number);
summary.unstaled++;
actionsTaken++;
} else if (staleAt <= closeCutoff) {
if (budgetExhausted()) { summary.skipped++; continue; }
await close(issue.number);
summary.closed++;
actionsTaken++;
}
continue;
}

if (exempt) {
summary.exempt++;
continue;
}

if (new Date(issue.updatedAt) <= staleCutoff) {
if (budgetExhausted()) { summary.skipped++; continue; }
await addStale(issue.number);
summary.staled++;
actionsTaken++;
}
}

const prefix = DRY_RUN ? 'DRY_RUN ' : '';
core.info(
`${prefix}scanned=${summary.scanned} staled=${summary.staled} ` +
`closed=${summary.closed} unstaled=${summary.unstaled} ` +
`exempt=${summary.exempt} skipped=${summary.skipped} ` +
`budget=${MAX_ACTIONS_PER_RUN}`,
);
};
20 changes: 0 additions & 20 deletions .github/stale.yml

This file was deleted.

Loading
Loading