diff --git a/.github/OSBotify-private-key.asc.gpg b/.github/OSBotify-private-key.asc.gpg deleted file mode 100644 index 03f0622..0000000 Binary files a/.github/OSBotify-private-key.asc.gpg and /dev/null differ diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f226b6d..41230e1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,12 +10,10 @@ on: concurrency: ${{ github.workflow }} jobs: - version: + get_pull_request: runs-on: ubuntu-latest - - # OSBotify will update the version on `main`, so this check is important to prevent an infinite loop - if: ${{ github.actor != 'OSBotify' }} - + outputs: + pull_request_number: ${{ steps.getMergedPullRequest.outputs.pull_request_number }} steps: - uses: actions/checkout@v3 with: @@ -27,71 +25,12 @@ jobs: with: github_token: ${{ github.token }} - - name: Decrypt & Import OSBotify GPG key - run: | - cd .github - gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output OSBotify-private-key.asc OSBotify-private-key.asc.gpg - gpg --import OSBotify-private-key.asc - env: - LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} - - - name: Set up git for OSBotify - run: | - git config --global user.signingkey AEE1036472A782AB - git config --global commit.gpgsign true - git config --global user.name OSBotify - git config --global user.email infra+osbotify@expensify.com - - - uses: actions/setup-node@v3 - with: - node-version: '16.x' - registry-url: 'https://registry.npmjs.org' - - - name: Generate branch name - run: echo "BRANCH_NAME=OSBotify-bump-version-$(uuidgen)" >> $GITHUB_ENV - - - name: Create branch for version-bump pull request - run: git checkout -b ${{ env.BRANCH_NAME }} - - - name: Install npm packages - run: npm ci - - - name: Update npm version - run: npm version patch - - - name: Set new version in GitHub ENV - run: echo "NEW_VERSION=$(jq '.version' package.json)" >> $GITHUB_ENV - - - name: Push branch and publish tags - run: git push --set-upstream origin ${{ env.BRANCH_NAME }} && git push --tags - - - name: Create pull request - run: | - gh pr create \ - --title "Update version to ${{ env.NEW_VERSION }}" \ - --body "Update version to ${{ env.NEW_VERSION }}" - sleep 5 - env: - GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} - - - name: Auto-approve pull request - run: gh pr review --approve ${{ env.BRANCH_NAME }} - env: - GITHUB_TOKEN: ${{ github.token }} - - - name: Auto-merge pull request - run: gh pr merge --merge --delete-branch ${{ env.BRANCH_NAME }} - env: - GITHUB_TOKEN: ${{ github.token }} - - - name: Publish to npm - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Comment on PR - run: | - gh pr comment ${{ steps.getMergedPullRequest.outputs.number }} --body \ - ":rocket: Published in ${{ env.NEW_VERSION }}" - env: - GITHUB_TOKEN: ${{ github.token }} + publish: + needs: get_pull_request + uses: Expensify/GitHub-Actions/.github/workflows/npmPublish.yml@main + with: + repository: ${{ github.action_repository }} + pull_request_number: ${{ needs.get_pull_request.outputs.pull_request_number }} + secrets: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + OS_BOTIFY_COMMIT_TOKEN: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }} diff --git a/eslint-plugin-expensify/CONST.js b/eslint-plugin-expensify/CONST.js index b4fcff9..79baf8f 100644 --- a/eslint-plugin-expensify/CONST.js +++ b/eslint-plugin-expensify/CONST.js @@ -33,6 +33,6 @@ module.exports = { PREFER_TYPE_FEST_TUPLE_TO_UNION: 'Prefer using `TupleToUnion` from `type-fest` for converting tuple types to union types.', PREFER_TYPE_FEST_VALUE_OF: 'Prefer using `ValueOf` from `type-fest` to extract the type of the properties of an object.', PREFER_AT: 'Prefer using the `.at()` method for array element access.', - PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH: 'Prefer using `shouldUseNarrowLayout` instead of `isSmallScreenWidth` from `useResponsiveLayout`.', + PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH: 'Prefer using `shouldUseNarrowLayout` instead of `isSmallScreenWidth` from `useResponsiveLayout`.', }, }; diff --git a/eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js b/eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js index 53030b9..b00d4a2 100644 --- a/eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js +++ b/eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js @@ -1,104 +1,104 @@ -const {AST_NODE_TYPES} = require("@typescript-eslint/utils"); -const _ = require("underscore"); -const CONST = require("./CONST"); +const {AST_NODE_TYPES} = require('@typescript-eslint/utils'); +const _ = require('underscore'); +const CONST = require('./CONST'); module.exports = { - meta: { - type: "problem", - docs: { - description: - "Warn against using isSmallScreenWidth from useResponsiveLayout and suggest using shouldUseNarrowLayout instead.", + meta: { + type: 'problem', + docs: { + description: + 'Warn against using isSmallScreenWidth from useResponsiveLayout and suggest using shouldUseNarrowLayout instead.', + }, + schema: [], }, - schema: [], - }, - create(context) { + create(context) { + // eslint-disable-next-line es/no-nullish-coalescing-operators + const sourceCode = context.sourceCode ?? context.getSourceCode(); - const sourceCode = context.sourceCode ?? context.getSourceCode(); + return { + VariableDeclarator(node) { + if ( + !node.init + || !node.init.callee + || node.init.callee.name !== 'useResponsiveLayout' + ) { + return; + } - return { - VariableDeclarator(node) { - if ( - !node.init || - !node.init.callee || - node.init.callee.name !== "useResponsiveLayout" - ) { - return; - } - - // Check for 'const {isSmallScreenWidth, ...} = useResponsiveLayout();' pattern - if (node.id.type === AST_NODE_TYPES.ObjectPattern) { - node.id.properties.forEach((property) => { - if (!property.key || property.key.name !== "isSmallScreenWidth") { - return; - } - context.report({ - node: property, - message: + // Check for 'const {isSmallScreenWidth, ...} = useResponsiveLayout();' pattern + if (node.id.type === AST_NODE_TYPES.ObjectPattern) { + node.id.properties.forEach((property) => { + if (!property.key || property.key.name !== 'isSmallScreenWidth') { + return; + } + context.report({ + node: property, + message: CONST.MESSAGE - .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, - }); - }); - } + .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, + }); + }); + } - const scope = sourceCode.getScope ? sourceCode.getScope(node) : context.getScope(); + const scope = sourceCode.getScope ? sourceCode.getScope(node) : context.getScope(); - // Check for 'const var = useResponsiveLayout();' and use of this var - const variableName = node.id.name; - const variableUsages = _.filter( - scope.references, - (reference) => reference.identifier.name === variableName - ); - variableUsages.forEach((usage) => { - const parent = usage.identifier.parent; + // Check for 'const var = useResponsiveLayout();' and use of this var + const variableName = node.id.name; + const variableUsages = _.filter( + scope.references, + reference => reference.identifier.name === variableName, + ); + variableUsages.forEach((usage) => { + const parent = usage.identifier.parent; - // Check for 'const isSmallScreenWidth = var.isSmallScreenWidth;' pattern - if ( - parent.type === AST_NODE_TYPES.MemberExpression && - parent.property.name === "isSmallScreenWidth" - ) { - context.report({ - node: parent.property, - message: + // Check for 'const isSmallScreenWidth = var.isSmallScreenWidth;' pattern + if ( + parent.type === AST_NODE_TYPES.MemberExpression + && parent.property.name === 'isSmallScreenWidth' + ) { + context.report({ + node: parent.property, + message: CONST.MESSAGE - .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, - }); - } + .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, + }); + } - // Check for 'const {isSmallScreenWidth} = var;' pattern - if ( - parent.type === AST_NODE_TYPES.VariableDeclarator && - parent.id.type === AST_NODE_TYPES.ObjectPattern - ) { - parent.id.properties.forEach((property) => { - if (!property.key || property.key.name !== "isSmallScreenWidth") { - return; - } - context.report({ - node: property, - message: + // Check for 'const {isSmallScreenWidth} = var;' pattern + if ( + parent.type === AST_NODE_TYPES.VariableDeclarator + && parent.id.type === AST_NODE_TYPES.ObjectPattern + ) { + parent.id.properties.forEach((property) => { + if (!property.key || property.key.name !== 'isSmallScreenWidth') { + return; + } + context.report({ + node: property, + message: CONST.MESSAGE - .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, - }); - }); - } - }); - }, - MemberExpression(node) { - // Check for 'const isSmallScreenWidth = useResponsiveLayout().isSmallScreenWidth;' pattern - if ( - node.object.type !== "CallExpression" || - node.object.callee.name !== "useResponsiveLayout" || - node.property.name !== "isSmallScreenWidth" - ) { - return; - } - context.report({ - node, - message: + .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, + }); + }); + } + }); + }, + MemberExpression(node) { + // Check for 'const isSmallScreenWidth = useResponsiveLayout().isSmallScreenWidth;' pattern + if ( + node.object.type !== 'CallExpression' + || node.object.callee.name !== 'useResponsiveLayout' + || node.property.name !== 'isSmallScreenWidth' + ) { + return; + } + context.report({ + node, + message: CONST.MESSAGE - .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, - }); - }, - }; - }, + .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH, + }); + }, + }; + }, }; diff --git a/eslint-plugin-expensify/tests/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.test.js b/eslint-plugin-expensify/tests/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.test.js index 523d3dd..d4499a5 100644 --- a/eslint-plugin-expensify/tests/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.test.js +++ b/eslint-plugin-expensify/tests/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.test.js @@ -1,74 +1,73 @@ -const RuleTester = require("eslint").RuleTester; -const rule = require("../prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth"); -const message = - require("../CONST").MESSAGE +const RuleTester = require('eslint').RuleTester; +const rule = require('../prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth'); +const message = require('../CONST').MESSAGE .PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH; const ruleTester = new RuleTester({ - parserOptions: { - ecmaVersion: 6, - sourceType: "module", - }, + parserOptions: { + ecmaVersion: 6, + sourceType: 'module', + }, }); ruleTester.run( - "prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth", - rule, - { - valid: [ - { - code: "const {shouldUseNarrowLayout} = useResponsiveLayout();", - }, - ], - invalid: [ - { - code: "const {isSmallScreenWidth} = useResponsiveLayout();", - errors: [ - { - message, - }, + 'prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth', + rule, + { + valid: [ + { + code: 'const {shouldUseNarrowLayout} = useResponsiveLayout();', + }, ], - }, - { - code: "const {isSmallScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout();", - errors: [ - { - message, - }, - ], - }, - { - code: ` + invalid: [ + { + code: 'const {isSmallScreenWidth} = useResponsiveLayout();', + errors: [ + { + message, + }, + ], + }, + { + code: 'const {isSmallScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout();', + errors: [ + { + message, + }, + ], + }, + { + code: ` const isSmallScreenWidth = useResponsiveLayout().isSmallScreenWidth; `, - errors: [ - { - message, - }, - ], - }, - { - code: ` + errors: [ + { + message, + }, + ], + }, + { + code: ` const dimensions = useResponsiveLayout(); const isSmallScreenWidth = dimensions.isSmallScreenWidth; `, - errors: [ - { - message, - }, - ], - }, - { - code: ` + errors: [ + { + message, + }, + ], + }, + { + code: ` const dimensions = useResponsiveLayout(); const {isSmallScreenWidth} = dimensions; `, - errors: [ - { - message, - }, + errors: [ + { + message, + }, + ], + }, ], - }, - ], - } + }, ); diff --git a/rules/expensify.js b/rules/expensify.js index dace182..f3e6076 100644 --- a/rules/expensify.js +++ b/rules/expensify.js @@ -28,7 +28,7 @@ module.exports = { message: 'Please use SafeAreaView from react-native-safe-area-context', }], }], - "rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth": "warn", + 'rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth': 'warn', }, };