commit 1d209e5c04b5f8031e00cdaff3f8880a320cd052
parent 26f66d9f223b54e1c35973acc2c4ef407ec72ae7
Author: Yuukin256 <52195426+Yuukin256@users.noreply.github.com>
Date: Sun, 5 May 2024 19:58:11 +0900
CIを設定 (#62)
* GitHub Actions で ESLint, Prettier, 型チェックを設定
* フォーマットを実行
Diffstat:
16 files changed, 130 insertions(+), 81 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
@@ -0,0 +1,48 @@
+name: CI
+
+on:
+ - pull_request
+
+jobs:
+ lint-format-type:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - uses: pnpm/action-setup@v3
+ name: Install pnpm
+ with:
+ version: 8
+ run_install: false
+
+ - name: Get pnpm store directory
+ shell: bash
+ run: |
+ echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
+
+ - uses: actions/cache@v4
+ name: Setup pnpm cache
+ with:
+ path: ${{ env.STORE_PATH }}
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ ${{ runner.os }}-pnpm-store-
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run ESLint
+ run: pnpm lint
+
+ - name: Run Prettier
+ run: pnpm prettier . --check
+
+ - name: Run type check
+ run: pnpm type-check
diff --git a/.lintstagedrc.yml b/.lintstagedrc.yml
@@ -1,2 +1,2 @@
'*.{js,ts,jsx,tsx}': ['npx eslint --fix']
-'*.{js,ts,jsx,tsx,json}': ['npx prettier --write']
+'*.{js,ts,jsx,tsx,json}': ['npx prettier . --write']
diff --git a/next.config.js b/next.config.js
@@ -28,7 +28,7 @@ const nextConfig = withPWA({
destination: '/' + className,
permanent: false,
};
- })
+ }),
);
const startDefaultRedirect = {
diff --git a/src/client/components/IconButtonDatePicker/index.tsx b/src/client/components/IconButtonDatePicker/index.tsx
@@ -13,7 +13,7 @@ const NothingField = function NothingField() {
};
export default memo(function IconButtonDatePicker(
- props: Omit<MobileDatePickerProps<Date>, 'open' | 'onOpen' | 'onClose'>
+ props: Omit<MobileDatePickerProps<Date>, 'open' | 'onOpen' | 'onClose'>,
) {
const ref = useRef<HTMLButtonElement | null>(null);
const [open, handlers] = useDisclosure(false);
diff --git a/src/client/components/Link/index.tsx b/src/client/components/Link/index.tsx
@@ -65,78 +65,79 @@ export type LinkProps = {
// A styled version of the Next.js Link component:
// https://nextjs.org/docs/api-reference/next/link
-const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link(
- props,
- ref
-) {
- const {
- activeClassName = 'active',
- as,
- className: classNameProps,
- href,
- legacyBehavior,
- linkAs: linkAsProp,
- locale,
- noLinkStyle,
- prefetch,
- replace,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- role, // Link don't have roles.
- scroll,
- shallow,
- ...other
- } = props;
+const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
+ function Link(props, ref) {
+ const {
+ activeClassName = 'active',
+ as,
+ className: classNameProps,
+ href,
+ legacyBehavior,
+ linkAs: linkAsProp,
+ locale,
+ noLinkStyle,
+ prefetch,
+ replace,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ role, // Link don't have roles.
+ scroll,
+ shallow,
+ ...other
+ } = props;
- const router = useRouter();
- const pathname = typeof href === 'string' ? href : href.pathname;
- const className = clsx(classNameProps, {
- [activeClassName]: router.pathname === pathname && activeClassName,
- });
+ const router = useRouter();
+ const pathname = typeof href === 'string' ? href : href.pathname;
+ const className = clsx(classNameProps, {
+ [activeClassName]: router.pathname === pathname && activeClassName,
+ });
- const isExternal =
- typeof href === 'string' &&
- (href.indexOf('http') === 0 || href.indexOf('mailto:') === 0);
+ const isExternal =
+ typeof href === 'string' &&
+ (href.indexOf('http') === 0 || href.indexOf('mailto:') === 0);
- if (isExternal) {
- if (noLinkStyle) {
- return <Anchor className={className} href={href} ref={ref} {...other} />;
+ if (isExternal) {
+ if (noLinkStyle) {
+ return (
+ <Anchor className={className} href={href} ref={ref} {...other} />
+ );
+ }
+
+ return <MuiLink className={className} href={href} ref={ref} {...other} />;
}
- return <MuiLink className={className} href={href} ref={ref} {...other} />;
- }
+ const linkAs = linkAsProp || as;
+ const nextjsProps = {
+ to: href,
+ linkAs,
+ replace,
+ scroll,
+ shallow,
+ prefetch,
+ legacyBehavior,
+ locale,
+ };
- const linkAs = linkAsProp || as;
- const nextjsProps = {
- to: href,
- linkAs,
- replace,
- scroll,
- shallow,
- prefetch,
- legacyBehavior,
- locale,
- };
+ if (noLinkStyle) {
+ return (
+ <NextLinkComposed
+ className={className}
+ ref={ref}
+ {...nextjsProps}
+ {...other}
+ />
+ );
+ }
- if (noLinkStyle) {
return (
- <NextLinkComposed
+ <MuiLink
+ component={NextLinkComposed}
className={className}
ref={ref}
{...nextjsProps}
{...other}
/>
);
- }
-
- return (
- <MuiLink
- component={NextLinkComposed}
- className={className}
- ref={ref}
- {...nextjsProps}
- {...other}
- />
- );
-});
+ },
+);
export default Link;
diff --git a/src/client/features/daily/components/DatePicker.tsx b/src/client/features/daily/components/DatePicker.tsx
@@ -34,7 +34,7 @@ export default function DatePickerWithSideButton({
const maxDate = dates[dates.length - 1];
const shouldDisableDate = useCallback(
(d1: Date) => dates.every((d2) => !isSameDay(d1, d2)),
- [dates]
+ [dates],
);
const canSelectToday = !shouldDisableDate(new Date());
diff --git a/src/client/features/daily/hooks/useIndexAndDate.ts b/src/client/features/daily/hooks/useIndexAndDate.ts
@@ -18,7 +18,7 @@ const useIndexAndDate = (dateStrings: string[]): Return => {
const size = dateStrings.length;
const dates = useMemo(
() => dateStrings.map((v) => new Date(v)),
- [dateStrings]
+ [dateStrings],
);
// 初期設定の日付: 16時以前なら当日; 16時以降なら翌日; その日の時間割がなければ最も近い未来の日付; 未来がなければ最も新しい日付
@@ -54,7 +54,7 @@ const useIndexAndDate = (dateStrings: string[]): Return => {
const dateString = dateStrings[index];
const date = useMemo(
() => (dateString ? new Date(dateString) : null),
- [dateString]
+ [dateString],
);
const setDate = useCallback(
@@ -64,7 +64,7 @@ const useIndexAndDate = (dateStrings: string[]): Return => {
setIndex(newIndex);
}
},
- [dateStrings]
+ [dateStrings],
);
return {
diff --git a/src/client/features/setting/components/MyClassForm.tsx b/src/client/features/setting/components/MyClassForm.tsx
@@ -47,7 +47,7 @@ export default function MyClassForm() {
});
}
},
- [enqueueSnackbar, removeCookieValue, setCookieValue]
+ [enqueueSnackbar, removeCookieValue, setCookieValue],
);
return (
diff --git a/src/client/features/setting/components/ThemeSwitch.tsx b/src/client/features/setting/components/ThemeSwitch.tsx
@@ -19,7 +19,7 @@ export default function ThemeSwitch() {
setMode(newMode);
}
},
- [setMode]
+ [setMode],
);
return (
diff --git a/src/client/hooks/useMap.ts b/src/client/hooks/useMap.ts
@@ -11,11 +11,11 @@ export interface Actions<K, V> {
type Return<K, V> = [
Omit<Map<K, V>, 'set' | 'clear' | 'delete'>,
- Actions<K, V>
+ Actions<K, V>,
];
function useMap<K, V>(
- initialState: MapOrEntries<K, V> = new Map()
+ initialState: MapOrEntries<K, V> = new Map(),
): Return<K, V> {
const [map, setMap] = useState(new Map(initialState));
diff --git a/src/client/hooks/useMyClass.ts b/src/client/hooks/useMyClass.ts
@@ -31,11 +31,11 @@ const useMyClass = (): Return => {
(update: GradeClass) => {
setCookie(DEFAULT_CLASS_COOKIE_KEY, update, { expires });
},
- [expires, setCookie]
+ [expires, setCookie],
);
const removeValue = useCallback(
() => removeCookie(DEFAULT_CLASS_COOKIE_KEY),
- [removeCookie]
+ [removeCookie],
);
if (gradeClassValidation.success) {
diff --git a/src/common/utils/formatDate.ts b/src/common/utils/formatDate.ts
@@ -6,7 +6,7 @@ import { DATE_FORMAT } from 'common/constant';
const formatDate = (
date: Parameters<typeof format>[0],
formatStr: string = DATE_FORMAT,
- options?: Parameters<typeof format>[2]
+ options?: Parameters<typeof format>[2],
) => {
return format(date, formatStr, { locale: ja, ...options });
};
diff --git a/src/pages/[class]/index.tsx b/src/pages/[class]/index.tsx
@@ -26,7 +26,7 @@ type PageProps = {
export const getStaticPaths: GetStaticPaths<UrlQuery> = async () => {
const paths = GRADES.flatMap((g) =>
- CLASSES.map((c) => ({ params: { class: `${g}-${c}` } }))
+ CLASSES.map((c) => ({ params: { class: `${g}-${c}` } })),
);
return {
@@ -80,7 +80,7 @@ export const getStaticProps: GetStaticProps<PageProps, UrlQuery> = async ({
/** 曜日時限からクラスの科目データを返す */
const makeOnePeriodData = (
- dayPeriod?: DayPeriodJa
+ dayPeriod?: DayPeriodJa,
): OnePeriod | undefined => {
if (dayPeriod) {
return {
@@ -109,12 +109,12 @@ export const getStaticProps: GetStaticProps<PageProps, UrlQuery> = async ({
period7: makeOnePeriodData(sch.period7),
},
];
- }
+ },
);
// 日付順に並び替える
const sorted = dayTimetableCalendar.toSorted(([, a], [, b]) =>
- compareAsc(a.date, b.date)
+ compareAsc(a.date, b.date),
);
return {
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
@@ -31,7 +31,7 @@ const StyledMaterialDesignContent = styled(MaterialDesignContent)(
'&.notistack-MuiContent-warning': {
backgroundColor: theme.vars.palette.warning.main,
},
- })
+ }),
);
interface MyAppProps extends AppProps<{ children: ReactNode }> {
diff --git a/src/server/context.ts b/src/server/context.ts
@@ -6,7 +6,7 @@ import type * as trpcNext from '@trpc/server/adapters/next';
// create context based of incoming request
// set as optional here so it can also be re-used for `getStaticProps()`
export const createContext = async (
- opts?: trpcNext.CreateNextContextOptions
+ opts?: trpcNext.CreateNextContextOptions,
) => {
return {
req: opts?.req,
diff --git a/src/server/routers/dayPeriodSchedule.ts b/src/server/routers/dayPeriodSchedule.ts
@@ -17,13 +17,13 @@ export const dayPeriodScheduleRouter = router({
grade: zodGrade,
startDate: z.string(),
endDate: z.string(),
- })
+ }),
)
.query<[string, DayScheduleWithDate][]>(async ({ input }) => {
const schedules = Object.entries(dayPeriodSchedules)
.filter(
([date]) =>
- isAfter(date, input.startDate) && isBefore(date, input.endDate)
+ isAfter(date, input.startDate) && isBefore(date, input.endDate),
)
.map(([date, allGradesSchedule]): [string, DayScheduleWithDate] => {
const schedule = { ...allGradesSchedule[`grade${input.grade}`] };