Skip to content

Commit 8b597ef

Browse files
authored
Merge branch 'main' into netlify-plugin-update1
2 parents 4604c39 + db04679 commit 8b597ef

17 files changed

+5194
-1300
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
* @netlify/netlify-dev @netlify/workflow
2-
docs/ @netlify/docs
1+
* @netlify/ecosystem-pod-frameworks @netlify/ecosystem-pod-marketplace
2+
docs/ @netlify/department-docs
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Sync CMS to Plugins Repository
2+
on:
3+
repository_dispatch:
4+
# sync_cms_to_repo is a bespoke type created for use with the CMS Webhook
5+
types: [sync_cms_to_repo]
6+
env:
7+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8+
jobs:
9+
sync-to-repo:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Git checkout
13+
uses: actions/checkout@v3
14+
- name: Using Node.js
15+
uses: actions/setup-node@v3
16+
with:
17+
node-version: '*'
18+
cache: 'npm'
19+
check-latest: true
20+
- name: Install dependencies
21+
run: npm install
22+
- name: Setup git config
23+
run: |
24+
git config user.name 'github-actions[bot]'
25+
git config user.email 'github-actions[bot]@users.noreply.github.com'
26+
- name: Sync CMS to repo
27+
env:
28+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
CMS_CHANGES: ${{ toJson(github.event.client_payload) }}
30+
31+
run: bin/sync_cms_to_repo.sh

.github/workflows/sync-to-cms.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Sync Plugins to CMS
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
jobs:
7+
sync-to-cms:
8+
# Only run if the merged PR wasn't an automated PR for synching from the cms to the repo
9+
if: github.event.pull_request.merged && !contains(github.event.pull_request.labels.*.name, 'cms_sync')
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Git checkout
13+
uses: actions/checkout@v3
14+
- name: Using Node.js
15+
uses: actions/setup-node@v3
16+
with:
17+
node-version: '*'
18+
cache: 'npm'
19+
check-latest: true
20+
- name: Install dependencies
21+
run: npm install
22+
- name: Sync plugins to CMS
23+
env:
24+
SANITY_API_TOKEN: ${{ secrets.SANITY_API_TOKEN }}
25+
SANITY_PROJECT_ID: ${{ secrets.SANITY_PROJECT_ID }}
26+
SANITY_DATASET: ${{ secrets.SANITY_DATASET }}
27+
run: npx tsx bin/sync_plugins_to_cms.js

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ node_modules
1010
/build
1111
.vscode
1212
.DS_Store
13+
.env
1314

1415
# Local Netlify folder
1516
.netlify

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,47 @@
11
# Changelog
22

3+
## [6.49.1](https://github.com/netlify/plugins/compare/v6.49.0...v6.49.1) (2022-10-07)
4+
5+
6+
### Bug Fixes
7+
8+
* update netlify-plugin-formspree version ([#873](https://github.com/netlify/plugins/issues/873)) ([ac8d416](https://github.com/netlify/plugins/commit/ac8d4166cfffd7c608262d86a7770a98f35d8c34))
9+
10+
## [6.49.0](https://github.com/netlify/plugins/compare/v6.48.0...v6.49.0) (2022-10-06)
11+
12+
13+
### Features
14+
15+
* update plugin @netlify/plugin-nextjs to version 4.24.3 ([#889](https://github.com/netlify/plugins/issues/889)) ([cc05897](https://github.com/netlify/plugins/commit/cc05897362769bb8596b8bbe67c312f57c3d8c8d))
16+
17+
## [6.48.0](https://github.com/netlify/plugins/compare/v6.47.0...v6.48.0) (2022-10-05)
18+
19+
20+
### Features
21+
22+
* update plugin @netlify/plugin-nextjs to version 4.24.2 ([#887](https://github.com/netlify/plugins/issues/887)) ([3b88d6e](https://github.com/netlify/plugins/commit/3b88d6e6fa29e7937d56afd8d692d9eefea907e8))
23+
24+
25+
### Bug Fixes
26+
27+
* corrected sync issue from CMS that included _key in compatibility array items ([#885](https://github.com/netlify/plugins/issues/885)) ([888c24b](https://github.com/netlify/plugins/commit/888c24b21bbed7d0e4c03dd1d6e18efca5ce3dcd))
28+
29+
## [6.47.0](https://github.com/netlify/plugins/compare/v6.46.0...v6.47.0) (2022-10-05)
30+
31+
32+
### Features
33+
34+
* added synchronization from CMS to repo ([#849](https://github.com/netlify/plugins/issues/849)) ([8872a09](https://github.com/netlify/plugins/commit/8872a097f59d9c502ef05856ba275ea0f672423e))
35+
* plugin synchronization from repository to CMS ([#820](https://github.com/netlify/plugins/issues/820)) ([39f8af1](https://github.com/netlify/plugins/commit/39f8af1b75ff0b83b019286d256dc352deba0250))
36+
* update plugin @netlify/plugin-lighthouse to version 3.5.0 ([#850](https://github.com/netlify/plugins/issues/850)) ([f4b4f47](https://github.com/netlify/plugins/commit/f4b4f47f5f0434bd932c1ff3cbdad3fc11ddf163))
37+
* update plugin @netlify/plugin-lighthouse to version 3.6.0 ([#851](https://github.com/netlify/plugins/issues/851)) ([7450749](https://github.com/netlify/plugins/commit/7450749a3b48f31dc3d2d661384d490818abd02c))
38+
* update plugin @netlify/plugin-lighthouse to version 3.7.0 ([#853](https://github.com/netlify/plugins/issues/853)) ([58e7564](https://github.com/netlify/plugins/commit/58e7564d775f7ed5b517237f0a46d425778b0d09))
39+
* update plugin @netlify/plugin-lighthouse to version 3.7.1 ([#869](https://github.com/netlify/plugins/issues/869)) ([19857e9](https://github.com/netlify/plugins/commit/19857e920c07ff8584b5b970aed17b8913ba4b6a))
40+
* update plugin @netlify/plugin-nextjs to version 4.23.2 ([#845](https://github.com/netlify/plugins/issues/845)) ([0881aa9](https://github.com/netlify/plugins/commit/0881aa9f0e0205123d95086c1ecaa75c34bb6cea))
41+
* update plugin @netlify/plugin-nextjs to version 4.23.3 ([#847](https://github.com/netlify/plugins/issues/847)) ([11b73ce](https://github.com/netlify/plugins/commit/11b73ce360e62ef31a0f3b15e6ab603d02d47d31))
42+
* update plugin @netlify/plugin-nextjs to version 4.24.0 ([#866](https://github.com/netlify/plugins/issues/866)) ([b231f4e](https://github.com/netlify/plugins/commit/b231f4ed32ad49ab3ca09aed38df0d99b7117b04))
43+
* update version of Cecil cache ([#854](https://github.com/netlify/plugins/issues/854)) ([12557d8](https://github.com/netlify/plugins/commit/12557d875ea143a04a8d454429f1bef50d998db6))
44+
345
## [6.46.0](https://github.com/netlify/plugins/compare/v6.45.0...v6.46.0) (2022-09-21)
446

547

README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,6 @@
22

33
[Build Plugins](https://docs.netlify.com/configure-builds/build-plugins) are a new way to extend the functionality of your build on Netlify. The [`plugins.json` file](./site/plugins.json) in this repository is used to generate the [Netlify plugins directory](https://app.netlify.com/plugins). Plugins in this directory can be installed directly through the Netlify UI.
44

5-
## Contributing
6-
7-
The Netlify Plugins directory is filled with plugins created by Netlify staff and members of the community like you. You can contribute to the directory in the following ways:
8-
9-
- [Add a plugin](./docs/CONTRIBUTING.md#add-a-plugin) you've written to the plugins directory.
10-
- [Update a plugin](./docs/CONTRIBUTING.md#update-a-plugin) you maintain that's already in the directory.
11-
- [Request directory deactivation](./docs/CONTRIBUTING.md#request-deactivation) for a plugin which is not being maintained.
12-
13-
Visit the repository [contributor guide](./docs/CONTRIBUTING.md) for details.
14-
15-
## Plugin review
16-
17-
If you're reviewing someone else's plugin, please check the following [document](docs/plugin_review.md).
18-
195
## Code of Conduct
206

217
This project and everyone participating in it is governed by a [code of conduct](./docs/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to conduct@netlify.com.

bin/sync_cms_to_plugins_repo.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { promises as fs } from 'fs'
2+
3+
import plugins from '../site/plugins.json'
4+
5+
import { updatePlugins } from './utils.js'
6+
7+
// eslint-disable-next-line n/prefer-global/process
8+
const changes = JSON.parse(process.env.CMS_CHANGES)
9+
10+
console.log('Checking for CMS updates...')
11+
console.log('Changes to synchronize', changes)
12+
console.log('Synchronizing changes to plugins repo...')
13+
const updatedPlugins = updatePlugins(changes, plugins)
14+
fs.writeFile('site/plugins.json', `${JSON.stringify(updatedPlugins, null, 2)}\n`)
15+
16+
console.log('Done synching CMS updates to plugins repo.')

bin/sync_cms_to_repo.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
PR_TITLE="chore: cms to repo sync"
2+
BRANCH_NAME="sync_cms_to_plugins_$(date +%s)"
3+
4+
git branch $BRANCH_NAME
5+
git switch $BRANCH_NAME
6+
7+
echo "Syncing CMS to plugins"
8+
npx tsx bin/sync_cms_to_plugins_repo.js
9+
10+
11+
# This is the only file we want to commit
12+
git add site/plugins.json
13+
14+
# See if we have any changes. We should.
15+
if [[ -n "$(git status --porcelain)" ]]; then
16+
echo "Creating PR \"$PR_TITLE\" for branch $BRANCH_NAME"
17+
git commit -m "$PR_TITLE"
18+
git push origin $BRANCH_NAME
19+
gh pr create --title "$PR_TITLE" --body "This is an automated PR to sync the CMS to the repo" --label "cms_sync" --label "automerge"
20+
else
21+
# Shouldn't end up here, but log that there was nothing to sync
22+
echo "Looks like there was nothing to sync."
23+
fi

bin/sync_plugins_to_cms.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// eslint-env node
2+
/* eslint-disable n/prefer-global/process */
3+
import { promises as fs } from 'fs'
4+
import path from 'path'
5+
6+
import sanityClient from '@sanity/client'
7+
import { uuid } from '@sanity/uuid'
8+
9+
// when testing this script locally, add a path in your .env for GITHUB_WORKSPACE or pass it in
10+
// e.g. GITHUB_WORKSPACE="$(pwd)" npx tsx bin/sync_plugins_to_cms.js
11+
12+
/**
13+
* @typedef { import("../types/plugins").SanityBuildPluginEntity } SanityBuildPluginEntity
14+
* @typedef { import("@sanity/client").SanityClient } SanityClient
15+
* @typedef { import("@sanity/client").Transaction } Transaction
16+
* @typedef { import("@sanity/client").Patch } Patch
17+
* @typedef { import("../types/plugins").BuildPluginEntity } BuildPluginEntity
18+
*/
19+
20+
import { getPluginDiffsForSanity, getSanityPluginLookup } from './utils.js'
21+
22+
if (process.env.NODE_ENV === 'development') {
23+
// Using dotenv for local development.
24+
console.log('running in development mode')
25+
26+
const dotenv = await import('dotenv')
27+
dotenv.config()
28+
}
29+
30+
const { GITHUB_WORKSPACE, SANITY_API_TOKEN, SANITY_PROJECT_ID, SANITY_DATASET } = process.env
31+
const [apiVersion] = new Date().toISOString().split('T')
32+
33+
const config = {
34+
projectId: SANITY_PROJECT_ID,
35+
dataset: SANITY_DATASET,
36+
apiVersion,
37+
token: SANITY_API_TOKEN,
38+
// make sure we have the freshest data when doing the diff with plugins.json
39+
useCdn: false,
40+
}
41+
42+
/**
43+
* Creates a transaction containing updates to plugins for the CMS
44+
*
45+
* @param {Transaction} transaction
46+
* @param {Patch} patch
47+
* @param {BuildPluginEntity[]} diffs
48+
* @returns
49+
*/
50+
const createUpdates = (transaction, patch, diffs) =>
51+
diffs.reduce((tx, plugin) => {
52+
const { _id, ...changes } = plugin
53+
const fieldUpdates = {}
54+
const fieldRemovals = []
55+
56+
for (const [key, value] of Object.entries(changes)) {
57+
// any property that is null needs to be unset instead of being set to null
58+
if (value === null) {
59+
fieldRemovals.push(key)
60+
} else {
61+
fieldUpdates[key] = value
62+
}
63+
}
64+
65+
const update = patch(_id).set(fieldUpdates)
66+
67+
if (fieldRemovals.length !== 0) {
68+
update.unset(fieldRemovals)
69+
}
70+
71+
tx.patch(update)
72+
73+
return tx
74+
}, transaction)
75+
76+
/**
77+
* @type {SanityClient}
78+
*/
79+
const client = sanityClient(config)
80+
81+
// These are the only fields to synch for the moment.
82+
const query = `*[_type == "buildPlugin"] {
83+
_id,
84+
packageName,
85+
version,
86+
compatibility[]
87+
}`
88+
89+
// TODO: Add a retry mechanism to handle network errors
90+
try {
91+
const pluginsFilePath = path.join(GITHUB_WORKSPACE, '/site/plugins.json')
92+
const fileContents = await fs.readFile(pluginsFilePath)
93+
const plugins = JSON.parse(fileContents).map((plugin) => {
94+
// Ensure if a compatibility field exists, that it has all the necessary fields to sync with Sanity
95+
if (plugin.compatibility) {
96+
// eslint-disable-next-line no-param-reassign
97+
plugin.compatibility = plugin.compatibility.map((compatibilityItem) => {
98+
const updatedCompatibilityItem = {
99+
// A _key property is required by Sanity so each array item can be identified in a collaborative way
100+
// See https://www.sanity.io/docs/array-type#92296c6c45ea
101+
_key: uuid(),
102+
...compatibilityItem,
103+
}
104+
105+
return updatedCompatibilityItem
106+
})
107+
}
108+
109+
return plugin
110+
})
111+
112+
console.info('Detecting plugin changes...')
113+
114+
/**
115+
* @type {SanityBuildPluginEntity[]}
116+
*/
117+
const sanityBuildPlugins = await client.fetch(query, {})
118+
const sanityPluginLookup = await getSanityPluginLookup(sanityBuildPlugins)
119+
const pluginDiffs = getPluginDiffsForSanity(sanityPluginLookup, plugins)
120+
121+
if (pluginDiffs.length === 0) {
122+
console.info('No plugin changes found.')
123+
} else {
124+
console.info(`Found ${pluginDiffs.length} plugins with changes`)
125+
console.info('Updating plugins...')
126+
127+
const transaction = createUpdates(client.transaction(), client.patch, pluginDiffs)
128+
129+
client.mutate(transaction)
130+
console.info('Plugins were updated in the CMS.')
131+
}
132+
} catch (error) {
133+
console.error(error)
134+
throw new Error('Unable to synchronize plugins to the CMS')
135+
}
136+
137+
/* eslint-enable n/prefer-global/process */

0 commit comments

Comments
 (0)