Skip to content

Commit

Permalink
Merge branch 'next' into valentin/migrate-version-to-use-workspace-sy…
Browse files Browse the repository at this point in the history
…ntax
  • Loading branch information
valentinpalkovic authored Jul 25, 2023
2 parents a1e8e5c + 7e0dabc commit aa8fe31
Show file tree
Hide file tree
Showing 24 changed files with 229 additions and 81 deletions.
10 changes: 10 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ Closes #
Everybody: Please submit all PRs to the `next` branch unless they are specific to the current release. Storybook maintainers cherry-pick bug and documentation fixes into the `main` branch as part of the release process, so you shouldn't need to worry about this. For additional guidance: https://storybook.js.org/docs/react/contribute/how-to-contribute
-->

### 🦋 Canary release

<!-- CANARY_RELEASE_SECTION -->

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the `@storybookjs/core` team here.

_core team members can create a canary release [here](https://github.com/storybookjs/storybook/actions/workflows/canary-release-pr.yml) or locally with `gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>`_

<!-- CANARY_RELEASE_SECTION -->
105 changes: 98 additions & 7 deletions .github/workflows/canary-release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
workflow_dispatch:
inputs:
pr:
description: 'Which pull request number to create a canary release for'
description: 'Pull request number to create a canary release for'
required: true
type: number

Expand All @@ -14,7 +14,7 @@ env:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 1

concurrency:
group: ${{ github.workflow }}-${{ inputs.pr }}
group: ${{ github.workflow }}-${{ github.event.inputs.pr }}
cancel-in-progress: true

permissions:
Expand All @@ -25,9 +25,100 @@ jobs:
name: Release canary version
runs-on: ubuntu-latest
environment: release
defaults:
run:
working-directory: scripts
steps:
- name: Do nothing
run: echo "I'm not doing anything"
- name: Fail if triggering actor is not administrator
uses: prince-chrismc/check-actor-permissions-action@v2.0.4
with:
permission: admin

- name: Get pull request information
id: info
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
PR_INFO=$(gh pr view ${{ inputs.pr }} --repo ${{ github.repository }} --json isCrossRepository,headRefOid,headRefName,headRepository,headRepositoryOwner --jq '{isFork: .isCrossRepository, owner: .headRepositoryOwner.login, repoName: .headRepository.name, branch: .headRefName, sha: .headRefOid}')
echo $PR_INFO
# Loop through each key-value pair in PR_INFO and set as step output
for key in $(echo "$PR_INFO" | jq -r 'keys[]'); do
value=$(echo "$PR_INFO" | jq -r ".$key")
echo "$key=$value" >> "$GITHUB_OUTPUT"
done
echo "repository=$(echo "$PR_INFO" | jq -r ".owner")/$(echo "$PR_INFO" | jq -r ".repoName")" >> $GITHUB_OUTPUT
echo "shortSha=$(echo "$PR_INFO" | jq -r ".sha" | cut -c 1-8)" >> $GITHUB_OUTPUT
echo "date=$(date)" >> $GITHUB_OUTPUT
echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@v3
with:
repository: ${{ steps.info.outputs.isFork == 'true' && steps.info.outputs.repository || null }}
ref: ${{ steps.info.outputs.sha }}
token: ${{ secrets.GH_TOKEN }}

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'

- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.yarn/berry/cache
key: yarn-v1-${{ hashFiles('scripts/yarn.lock') }}-${{ hashFiles('code/yarn.lock') }}
restore-keys: |
yarn-v1-${{ hashFiles('scripts/yarn.lock') }}-${{ hashFiles('code/yarn.lock') }}
yarn-v1-${{ hashFiles('scripts/yarn.lock') }}
yarn-v1
- name: Install dependencies
run: yarn task --task=install --start-from=install

- name: Set version
id: version
working-directory: scripts
run: |
yarn release:version --release-type prerelease --pre-id canary-${{ inputs.pr }}-${{ steps.info.outputs.timestamp }}-${{ steps.info.outputs.shortSha }} --verbose
- name: Publish v${{ steps.version.outputs.next-version }}
env:
YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
working-directory: scripts
run: yarn release:publish --tag canary --verbose

- name: Replace Pull Request Body
# TODO: replace with ivangabriele/find-and-replace-pull-request-body@vX when https://github.com/ivangabriele/find-and-replace-pull-request-body/pull/11 has been released
uses: mcky/find-and-replace-pull-request-body@v1.1.6-mcky
with:
githubToken: ${{ secrets.GH_TOKEN }}
prNumber: ${{ inputs.pr }}
find: 'CANARY_RELEASE_SECTION'
isHtmlCommentTag: true
replace: |
This pull request has been released as version [`${{ steps.version.outputs.next-version }}`](https://npmjs.com/package/@storybook/cli/v/${{ steps.version.outputs.next-version }}). Install it by pinning all your Storybook dependencies to that version.
<details>
<summary>More information</summary>
| | |
| --- | --- |
| **Published version** | [`${{ steps.version.outputs.next-version }}`](https://npmjs.com/package/@storybook/cli/v/${{ steps.version.outputs.next-version }}) |
| **Triggered by** | @${{ github.triggering_actor }} |
| **Repository** | [${{ steps.info.outputs.repository }}](https://github.com/${{ steps.info.outputs.repository }}) |
| **Branch** | [`${{ steps.info.outputs.branch }}`](https://github.com/${{ steps.info.outputs.repository }}/tree/${{ steps.info.outputs.branch }}) |
| **Commit** | [`${{ steps.info.outputs.shortSha }}`](https://github.com/${{ steps.info.outputs.repository }}/commit/${{ steps.info.outputs.sha }}) |
| **Datetime** | ${{ steps.info.outputs.date }} (`${{ steps.info.outputs.timestamp }}`) |
| **Workflow run** | [${{ github.run_id }}](https://github.com/storybookjs/storybook/actions/runs/${{ github.run_id }}) |
To request a new release of this pull request, mention the `@storybookjs/core` team.
_core team members can create a new canary release [here](https://github.com/storybookjs/storybook/actions/workflows/canary-release-pr.yml) or locally with `gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=${{ inputs.pr }}`_
</details>
- name: Create failing comment on PR
if: failure()
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
gh pr comment ${{ inputs.pr }}\
--repo "${{github.repository }}"\
--body "Failed to publish canary version of this pull request, triggered by @${{ github.triggering_actor }}. See the failed workflow run at: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 7.1.1

- Angular: Make enableProdMode optional - [#23489](https://github.com/storybookjs/storybook/pull/23489), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!
- CLI: Gracefully shutdown and cleanup execa child processes - [#23538](https://github.com/storybookjs/storybook/pull/23538), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!
- CLI: Improve support of mono repositories - [#23458](https://github.com/storybookjs/storybook/pull/23458), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!

## 7.1.0 (July 18, 2023)

Storybook 7.1 is here! 🎉
Expand Down
47 changes: 46 additions & 1 deletion CONTRIBUTING/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,52 @@ Before you start you should make sure that your working tree is clean and the re

## Canary Releases

Not implemented yet. Still work in progress, stay tuned.
It's possible to release any pull request as a canary release multiple times during development. This is an effective way to try out changes in standalone projects without linking projects together via package managers.

To create a canary release, a core team member (or anyone else with administrator privileges) must manually trigger the canary release workflow.

**Before creating a canary release from contributors, the core team member must ensure that the code being released is not malicious.**

Creating a canary release can either be done via GitHub's UI or the [CLI](https://cli.github.com/):

### With GitHub UI

1. Open the workflow UI at https://github.com/storybookjs/storybook/actions/workflows/canary-release-pr.yml
2. On the top right corner, click "Run workflow"
3. For "branch", **always select `next`**, regardless of which branch your pull request is on
4. For the pull request number, input the number for the pull request **without a leading #**

### With the CLI

The following command will trigger a workflow run - replace `<PR_NUMBER>` with the actual pull request number:

```bash
gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>
```

When the release succeeds, it will update the "Canary release" section of the pull request with information about the release and how to use it (see example [here](https://github.com/storybookjs/storybook/pull/23508)). If it fails, it will create a comment on the pull request, tagging the triggering actor to let them know that it failed (see example [here](https://github.com/storybookjs/storybook/pull/23508#issuecomment-1642850467)).

The canary release will have the following version format: `<CURRENT_VERSION>-canary-<PR_NUMBER>-<TIMESTAMP>-<COMMIT_SHA>.0`, e.g., `7.1.1-canary-23508-1689802571-5ec8c1c3.0`.

- The current version has no actual meaning but softly indicates which version the pull request is based on (e.g., a pull request based on v7.1.0 will get released as a canary version of v7.1.1).
- The timestamp ensures that any subsequent releases are always considered newer.
- The commit hash indicates which exact code has been released.

> ** Note **
> All canary releases are released under the same "canary" dist tag. This means you'll technically be able to install it with `npm install @storybook/cli@canary`. However, this doesn't make sense, as releases from subsequent pull requests will overwrite that tag quickly. Therefore you should always install the specific version string, e.g., `npm install @storybook/cli@7.1.1-canary-23508-1689802571-5ec8c1c3.0.
<details>
<summary>Isn't there a simpler/smarter way to do this?</summary>

The simple approach would be to release canaries for all pull requests automatically; however, this would be insecure as any contributor with Write privileges to the repository (200+ users) could create a malicious pull request that alters the release script to release a malicious release (e.g., release a patch version that adds a crypto miner).

To alleviate this, we only allow the "Release" GitHub environment that contains the npm token to be accessible from workflows running on the protected branches (`next`, `main`, etc.).

You could also be tempted to require approval from admins before running the workflows. However, this would spam the core team with GitHub notifications for workflow runs seeking approval - even when a core team member triggered the workflow. Therefore we are doing it the other way around, requiring contributors and maintainers to ask for a canary release to be created explicitly.

Instead of triggering the workflow manually, you could also do something smart, like trigger it when there's a specific label on the pull request or when someone writes a specific comment on the pull request. However, this would create a lot of unnecessary workflow runs because there isn't a way to filter workflow runs based on labels or comment content. The only way to achieve this would be to trigger the workflow on every comment/labeling, then cancel it if it didn't contain the expected content, which is inefficient.

</details>

## Versioning Scenarios

Expand Down
2 changes: 1 addition & 1 deletion code/addons/highlight/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Highlight DOM nodes by emitting the `HIGHLIGHT` event from within a story or an
import React, { useEffect } from 'react';
import { useChannel } from '@storybook/preview-api';
import { HIGHLIGHT, RESET_HIGHLIGHT } from '@storybook/addon-highlight';
import { MyComponent } form './MyComponent';
import { MyComponent } from './MyComponent';

export default { component: MyComponent };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import AngularSnapshotSerializer from 'jest-preset-angular/build/serializers/ng-
import HTMLCommentSerializer from 'jest-preset-angular/build/serializers/html-comment';
import { TestBed } from '@angular/core/testing';
import { addSerializer } from 'jest-specific-snapshot';
import { getApplication, storyPropsProvider } from '@storybook/angular/renderer';
import { getApplication, storyPropsProvider, PropertyExtractor } from '@storybook/angular/renderer';
import { BehaviorSubject } from 'rxjs';

addSerializer(HTMLCommentSerializer);
Expand All @@ -11,11 +11,14 @@ addSerializer(AngularSnapshotSerializer);
function getRenderedTree(story: any) {
const currentStory = story.render();

const analyzedMetadata = new PropertyExtractor(currentStory.moduleMetadata, story.component);

const application = getApplication({
storyFnAngular: currentStory,
component: story.component,
// TODO : To change with the story Id in v7. Currently keep with static id to avoid changes in snapshots
targetSelector: 'storybook-wrapper',
analyzedMetadata,
});

TestBed.configureTestingModule({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getApplication = ({
storyFnAngular: StoryFnAngularReturnType;
component?: any;
targetSelector: string;
analyzedMetadata?: PropertyExtractor;
analyzedMetadata: PropertyExtractor;
}) => {
const { props, styles, moduleMetadata = {} } = storyFnAngular;
let { template } = storyFnAngular;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const createStorybookWrapperComponent = ({
styles: string[];
moduleMetadata: NgModuleMetadata;
initialProps?: ICollection;
analyzedMetadata?: PropertyExtractor;
analyzedMetadata: PropertyExtractor;
}): Type<any> => {
// In ivy, a '' selector is not allowed, therefore we need to just set it to anything if
// storyComponent was not provided.
Expand Down
1 change: 1 addition & 0 deletions code/frameworks/angular/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { computesTemplateSourceFromComponent } from './client/angular-beta/Compu
export { rendererFactory } from './client/render';
export { AbstractRenderer } from './client/angular-beta/AbstractRenderer';
export { getApplication } from './client/angular-beta/StorybookModule';
export { PropertyExtractor } from './client/angular-beta/utils/PropertyExtractor';
2 changes: 1 addition & 1 deletion code/lib/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"puppeteer-core": "^2.1.1",
"read-pkg-up": "^7.0.1",
"semver": "^7.3.7",
"simple-update-notifier": "^1.0.0",
"simple-update-notifier": "^2.0.0",
"strip-json-comments": "^3.0.1",
"tempy": "^1.0.1",
"ts-dedent": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion code/lib/core-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@types/picomatch": "^2.3.0",
"mock-fs": "^5.2.0",
"slash": "^5.0.0",
"type-fest": "^3.11.0",
"type-fest": "~2.19",
"typescript": "~4.9.3"
},
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion code/lib/types/src/modules/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export interface Addon_BaseAnnotations<

/**
* ArgTypes encode basic metadata for args, such as `name`, `description`, `defaultValue` for an arg. These get automatically filled in by Storybook Docs.
* @see [Control annotations](https://github.com/storybookjs/storybook/blob/91e9dee33faa8eff0b342a366845de7100415367/addons/controls/README.md#control-annotations)
* @see [Arg types](https://storybook.js.org/docs/react/api/arg-types)
*/
argTypes?: Addons_ArgTypes<TArgs>;

Expand Down
2 changes: 1 addition & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"playwright": "1.36.0",
"playwright-core": "1.36.0",
"serialize-javascript": "^3.1.0",
"type-fest": "^3.11.0"
"type-fest": "~2.19"
},
"dependencies": {
"@babel/core": "^7.22.9",
Expand Down
2 changes: 1 addition & 1 deletion code/renderers/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"prop-types": "^15.7.2",
"react-element-to-jsx-string": "^15.0.0",
"ts-dedent": "^2.0.0",
"type-fest": "^3.11.0",
"type-fest": "~2.19",
"util-deprecate": "^1.0.2"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion code/renderers/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"@storybook/preview-api": "workspace:*",
"@storybook/types": "workspace:*",
"sveltedoc-parser": "^4.2.1",
"type-fest": "^3.11.0"
"type-fest": "~2.19"
},
"devDependencies": {
"expect-type": "^0.15.0",
Expand Down
2 changes: 1 addition & 1 deletion code/renderers/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@storybook/preview-api": "workspace:*",
"@storybook/types": "workspace:*",
"ts-dedent": "^2.0.0",
"type-fest": "^3.11.0"
"type-fest": "~2.19"
},
"devDependencies": {
"typescript": "~4.9.3",
Expand Down
Loading

0 comments on commit aa8fe31

Please sign in to comment.