Skip to content
Merged
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
21 changes: 21 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets).

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md).

## Adding a changeset

When you make a change that affects how this action behaves for consumers, run:

```sh
yarn changeset
```

Pick the bump type (patch / minor / major), write a short summary, and commit the generated
file in this folder alongside your change. On merge to `main`, Changesets opens a "Version
Packages" PR that applies the bumps and updates the changelog; merging that PR publishes the
release tag.
202 changes: 202 additions & 0 deletions .changeset/changelog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/**
* Custom Changesets changelog generator.
*
* Changesets hardcodes the changelog *scaffold* — the `# package` title, the
* `## version` headers, and the `### Major/Minor/Patch Changes` sections. This
* module shapes only the *bullet lines* under those sections into clean,
* human-readable markdown that renders as-is, with no post-processing:
*
* - A short summary headline. ([#12](pr-link)) — thanks [@user](user-link)!
* Continuation paragraphs from the changeset body, indented to stay in the item.
*
* The description leads so entries read like a sentence; the PR/commit and
* author links trail the headline so they stay out of the way. Single-line
* entries form a compact (tight) list.
*
* Links are resolved from the commit that introduced the changeset via
* `@changesets/get-github-info`, which needs `GITHUB_TOKEN` at `changeset
* version` time (CI provides it; contributors don't run versioning locally).
* Authors, and a specific PR or commit, can be overridden with magic lines in
* the changeset summary:
*
* pr: 123
* commit: a1b2c3d
* author: @octocat
*
* "thanks" is shown only for *external* contributors — authors whose handle is
* not in the `maintainers` allowlist (case-insensitive). On a change co-authored
* by a maintainer and an outside contributor, only the outsider is thanked.
*
* Config (.changeset/config.json):
* "changelog": ["./changelog.js", {
* "repo": "org/repo",
* "maintainers": ["octocat"], // internal handles — never thanked
* "disableThanks": false // set true to drop thanks entirely
* }]
*
* @typedef {import('@changesets/types').ChangelogFunctions} ChangelogFunctions
*/

import { getInfo, getInfoFromPullRequest } from "@changesets/get-github-info";

const GITHUB_SERVER_URL = process.env.GITHUB_SERVER_URL || "https://github.com";

/**
* Validate and return the required `repo` option, with a helpful message.
*
* @param {{ repo?: string } | null} options
* @returns {string}
*/
function requireRepo(options) {
if (!options || !options.repo) {
throw new Error(
"Please provide a repo to the changelog generator in .changeset/config.json:\n" +
'"changelog": ["./changelog.js", { "repo": "org/repo" }]',
);
}
return options.repo;
}

/**
* Turn bare `#123` issue/PR references into links, leaving existing markdown
* links untouched (the left alternative consumes them so the right only ever
* matches a bare ref).
*
* @param {string} line
* @param {string} repo
* @returns {string}
*/
function linkifyIssueRefs(line, repo) {
return line.replace(/\[.*?\]\(.*?\)|\B#([1-9]\d*)\b/g, (match, issue) =>
issue ? `[#${issue}](${GITHUB_SERVER_URL}/${repo}/issues/${issue})` : match,
);
}

/**
* Pull `pr:` / `commit:` / `author:` override lines out of a changeset summary,
* returning the cleaned summary plus whatever was found.
*
* @param {string} summary
* @returns {{ cleaned: string, pr?: number, commit?: string, authors: string[] }}
*/
function extractMeta(summary) {
let pr;
let commit;
const authors = [];
const cleaned = summary
.replace(
/^[ \t]*(?:pr|pull|pull\s+request):\s*#?(\d+)[ \t]*$/im,
(_match, n) => {
pr = Number(n);
return "";
},
)
.replace(/^[ \t]*commit:\s*(\S+)[ \t]*$/im, (_match, c) => {
commit = c;
return "";
})
.replace(/^[ \t]*(?:author|user):\s*@?(\S+)[ \t]*$/gim, (_match, u) => {
authors.push(u);
return "";
})
.trim();
return { cleaned, pr, commit, authors };
}

/**
* Resolve the trailing reference link (PR, else commit) and the change's
* authors for a changeset. Only hits the GitHub API when there's a PR or commit
* to look up. Each author carries its raw `login` (for the maintainer check)
* and its rendered markdown `link`.
*
* @param {string} repo
* @param {{ pr?: number, commit?: string, authors: string[] }} meta
* @param {string | undefined} changesetCommit
* @returns {Promise<{ reference: string | null, authors: { login: string, link: string }[] }>}
*/
async function resolveLinks(repo, meta, changesetCommit) {
let info = { user: null, links: { pull: null, commit: null, user: null } };
if (meta.pr !== undefined) {
info = await getInfoFromPullRequest({ repo, pull: meta.pr });
} else {
const commit = meta.commit || changesetCommit;
if (commit) info = await getInfo({ repo, commit });
}
let { links } = info;
// An explicit `commit:` override wins over a PR's merge commit.
if (meta.commit) {
const short = meta.commit.slice(0, 7);
links = {
...links,
commit: `[\`${short}\`](${GITHUB_SERVER_URL}/${repo}/commit/${meta.commit})`,
};
}
// `author:` overrides win; otherwise fall back to the resolved commit/PR author.
const authors = meta.authors.length
? meta.authors.map((login) => ({
login,
link: `[@${login}](${GITHUB_SERVER_URL}/${login})`,
}))
: info.user
? [{ login: info.user, link: links.user }]
: [];
return { reference: links.pull || links.commit, authors };
}

/** @type {ChangelogFunctions} */
const changelogFunctions = {
getReleaseLine: async (changeset, _type, options) => {
const repo = requireRepo(options);
const {
cleaned,
pr,
commit,
authors: authorOverrides,
} = extractMeta(changeset.summary);
const { reference, authors } = await resolveLinks(
repo,
{ pr, commit, authors: authorOverrides },
changeset.commit,
);

const [headline, ...rest] = cleaned
.split("\n")
.map((line) => line.trimEnd());

// Thank only external contributors — anyone not on the maintainer allowlist.
const maintainers = new Set(
(options.maintainers ?? []).map((handle) => handle.toLowerCase()),
);
const external = authors.filter(
(author) => !maintainers.has(author.login.toLowerCase()),
);

let suffix = "";
if (reference) suffix += ` (${reference})`;
if (external.length && !options.disableThanks)
suffix += ` — thanks ${external.map((author) => author.link).join(", ")}!`;

// Continuation lines are indented two spaces so multi-paragraph entries
// stay inside the list item; blank lines are preserved as paragraph breaks.
const body = rest
.map((line) => (line ? ` ${linkifyIssueRefs(line, repo)}` : ""))
.join("\n");

return `- ${linkifyIssueRefs(headline, repo)}${suffix}${body ? `\n${body}` : ""}`;
},

getDependencyReleaseLine: async (
_changesets,
dependenciesUpdated,
options,
) => {
requireRepo(options);
if (dependenciesUpdated.length === 0) return "";
const updated = dependenciesUpdated.map(
(dep) => ` - \`${dep.name}@${dep.newVersion}\``,
);
return ["- Updated dependencies:", ...updated].join("\n");
},
};

export default changelogFunctions;
12 changes: 12 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
"access": "public",
"baseBranch": "main",
"changelog": [
"./changelog.js",
{
"maintainers": ["castastrophe"],
"repo": "allonsy-studio/postcss-licensing"
}
]
}
5 changes: 5 additions & 0 deletions .changeset/flat-toes-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@allons-y/postcss-licensing": major
---

Migrate build resources to ESM in alignment with latest PostCSS changes.
35 changes: 35 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
changelog:
exclude:
labels:
- skip-changelog
categories:
- title: "✨ Features"
labels:
- "feat"
- title: "🐛 Bug Fixes"
labels:
- "fix"
- title: "⚡ Performance Improvements"
labels:
- "perf"
- title: "⏪ Reverts"
labels:
- "revert"
- title: "📚 Documentation"
labels:
- "docs"
- title: "♻️ Refactoring"
labels:
- "refactor"
- title: "🔧 Maintenance"
labels:
- "chore"
- title: "✅ Tests"
labels:
- "test"
- title: "📦 Build System"
labels:
- "build"
- title: "👷 CI"
labels:
- "ci"
48 changes: 24 additions & 24 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"baseBranchPatterns": ["main"],
"extends": [
"config:recommended",
":widenPeerDependencies",
"group:githubArtifactActions"
],
"labels": [],
"packageRules": [
{
"matchDatasources": ["npm"],
"minimumReleaseAge": "1 month"
},
{
"groupName": "commitlint ecosystem",
"matchPackageNames": ["commitlint", "@commitlint/*"]
}
],
"rebaseWhen": "behind-base-branch",
"reviewers": ["castastrophe"],
"lockFileMaintenance": {
"enabled": true,
"extends": ["schedule:monthly"]
}
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"baseBranchPatterns": ["main"],
"extends": [
"config:recommended",
":widenPeerDependencies",
"group:githubArtifactActions"
],
"labels": [],
"lockFileMaintenance": {
"enabled": true,
"extends": ["schedule:monthly"]
},
"packageRules": [
{
"matchDatasources": ["npm"],
"minimumReleaseAge": "1 month"
},
{
"groupName": "changesets ecosystem",
"matchPackageNames": ["@changesets/*"]
}
],
"rebaseWhen": "behind-base-branch",
"reviewers": ["castastrophe"]
}
45 changes: 45 additions & 0 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Linting

on:
pull_request:
types: [opened, synchronize, reopened]

# Least privilege by default; jobs opt into the extra scopes they need.
permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest
# reviewdog posts inline review comments and a check run.
permissions:
contents: read
checks: write
pull-requests: write
steps:
- name: Check out code
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Enable corepack
run: corepack enable

- name: Setup Node
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: yarn

- name: Install dependencies
run: yarn install --immutable

# Lint with the project's flat config (eslint.config.js) and surface
# findings as inline PR review comments via reviewdog.
- name: Run eslint via reviewdog
uses: reviewdog/action-eslint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
fail_level: error
eslint_flags: "."
Loading