Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 70d7099abe Fix cron-parser import to use named exports instead of default import
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
2025-11-07 16:25:32 +00:00
copilot-swe-agent[bot] b90107f524 Initial plan 2025-11-07 16:08:27 +00:00
9 changed files with 15 additions and 351 deletions
-150
View File
@@ -261,153 +261,3 @@ jobs:
- name: Image digest
run: |
echo ${{ steps.docker_build_310.outputs.digest }}
build-debian:
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: "8.3.1"
- uses: actions/setup-node@v4
with:
cache: "pnpm"
- name: Setup timezone
uses: szenius/set-timezone@v2.0
with:
timezoneLinux: Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta-debian
uses: docker/metadata-action@v5
with:
images: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
# generate Docker tags based on the following events/attributes
# nightly, master, pr-2, 1.2.3, 1.2, 1
flavor: |
latest=false
suffix=-debian,onlatest=true
tags: |
type=schedule,pattern=nightly
type=edge
type=ref,event=pr
type=ref,event=branch,enable=${{ github.ref != format('refs/heads/{0}', 'master') }}
type=raw,value=debian,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push Debian
id: docker_build_debian
uses: docker/build-push-action@v6
with:
build-args: |
MAINTAINER=${{ github.repository_owner }}
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64
context: .
file: ./docker/debian.Dockerfile
push: true
tags: ${{ steps.meta-debian.outputs.tags }}
labels: ${{ steps.meta-debian.outputs.labels }}
cache-from: type=registry,ref=whyour/qinglong:cache-debian
cache-to: type=registry,ref=whyour/qinglong:cache-debian,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build_debian.outputs.digest }}
build-debian-310:
if: ${{ github.ref_name == 'master' }}
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: "8.3.1"
- uses: actions/setup-node@v4
with:
cache: "pnpm"
- name: Setup timezone
uses: szenius/set-timezone@v2.0
with:
timezoneLinux: Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push Debian python3.10
id: docker_build_debian_310
uses: docker/build-push-action@v6
with:
build-args: |
MAINTAINER=${{ github.repository_owner }}
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64
context: .
file: ./docker/debian-310.Dockerfile
push: true
tags: whyour/qinglong:debian-python3.10
cache-from: type=registry,ref=whyour/qinglong:cache-debian-python3.10
cache-to: type=registry,ref=whyour/qinglong:cache-debian-python3.10,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build_debian_310.outputs.digest }}
+3 -3
View File
@@ -3,7 +3,7 @@ import { Container } from 'typedi';
import { Logger } from 'winston';
import SubscriptionService from '../services/subscription';
import { celebrate, Joi } from 'celebrate';
import cron_parser from 'cron-parser';
import { parseExpression } from 'cron-parser';
const route = Router();
export default (app: Router) => {
@@ -60,7 +60,7 @@ export default (app: Router) => {
try {
if (
!req.body.schedule ||
cron_parser.parseExpression(req.body.schedule).hasNext()
parseExpression(req.body.schedule).hasNext()
) {
const subscriptionService = Container.get(SubscriptionService);
const data = await subscriptionService.create(req.body);
@@ -193,7 +193,7 @@ export default (app: Router) => {
if (
!req.body.schedule ||
typeof req.body.schedule === 'object' ||
cron_parser.parseExpression(req.body.schedule).hasNext()
parseExpression(req.body.schedule).hasNext()
) {
const subscriptionService = Container.get(SubscriptionService);
const data = await subscriptionService.update(req.body);
+4 -4
View File
@@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs/promises';
import chokidar from 'chokidar';
import chokidar, { FSWatcher } from 'chokidar';
import config from '../config/index';
import { fileExist, promiseExec, rmPath } from '../config/util';
@@ -55,9 +55,9 @@ export default async (src: string = 'deps') => {
const watcher = chokidar.watch(source, {
ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true,
});
}) as any;
watcher
.on('add', (path) => linkToNodeModule(src))
.on('change', (path) => linkToNodeModule(src));
.on('add', (_path: string) => linkToNodeModule(src))
.on('change', (_path: string) => linkToNodeModule(src));
};
+2 -2
View File
@@ -4,7 +4,7 @@ import config from '../config';
import { Crontab, CrontabModel, CrontabStatus } from '../data/cron';
import { exec, execSync } from 'child_process';
import fs from 'fs/promises';
import cron_parser from 'cron-parser';
import { parseExpression } from 'cron-parser';
import {
getFileContentByName,
fileExist,
@@ -670,7 +670,7 @@ export default class CronService {
if (
command &&
schedule &&
cron_parser.parseExpression(schedule).hasNext()
parseExpression(schedule).hasNext()
) {
const name = namePrefix + '_' + index;
+2 -2
View File
@@ -1,5 +1,5 @@
import { Joi } from 'celebrate';
import cron_parser from 'cron-parser';
import { parseExpression } from 'cron-parser';
import { ScheduleType } from '../interface/schedule';
const validateSchedule = (value: string, helpers: any) => {
@@ -11,7 +11,7 @@ const validateSchedule = (value: string, helpers: any) => {
}
try {
if (cron_parser.parseExpression(value).hasNext()) {
if (parseExpression(value).hasNext()) {
return value;
}
} catch (e) {
-93
View File
@@ -1,93 +0,0 @@
FROM python:3.10-slim-bookworm AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends nodejs npm git ca-certificates \
&& npm i -g pnpm@8.3.1 pm2 ts-node \
&& cd /tmp/build \
&& pnpm install --prod \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
FROM python:3.10-slim-bookworm
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
ARG QL_BRANCH=develop
ARG PYTHON_SHORT_VERSION=3.10
ENV QL_DIR=/ql \
QL_BRANCH=${QL_BRANCH} \
LANG=C.UTF-8 \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ " \
DEBIAN_FRONTEND=noninteractive
VOLUME /ql/data
EXPOSE 5700
COPY --from=builder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/bin/. /usr/local/bin/
RUN set -x \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
nodejs \
jq \
openssh-client \
procps \
netcat-openbsd \
unzip \
npm \
cron \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& git config --global user.email "qinglong@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& rm -rf /root/.cache
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \
&& cd ${QL_DIR} \
&& cp -f .env.example .env \
&& chmod 777 ${QL_DIR}/shell/*.sh \
&& chmod 777 ${QL_DIR}/docker/*.sh \
&& git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /static \
&& mkdir -p ${QL_DIR}/static \
&& cp -rf /static/* ${QL_DIR}/static \
&& rm -rf /static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules:${PNPM_HOME}/global/5/node_modules \
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://127.0.0.1:5700/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
-93
View File
@@ -1,93 +0,0 @@
FROM python:3.11-slim-bookworm AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends nodejs npm git ca-certificates \
&& npm i -g pnpm@8.3.1 pm2 ts-node \
&& cd /tmp/build \
&& pnpm install --prod \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
FROM python:3.11-slim-bookworm
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
ARG QL_BRANCH=develop
ARG PYTHON_SHORT_VERSION=3.11
ENV QL_DIR=/ql \
QL_BRANCH=${QL_BRANCH} \
LANG=C.UTF-8 \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ " \
DEBIAN_FRONTEND=noninteractive
VOLUME /ql/data
EXPOSE 5700
COPY --from=builder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/bin/. /usr/local/bin/
RUN set -x \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
nodejs \
jq \
openssh-client \
procps \
netcat-openbsd \
unzip \
npm \
cron \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& git config --global user.email "qinglong@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& rm -rf /root/.cache
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \
&& cd ${QL_DIR} \
&& cp -f .env.example .env \
&& chmod 777 ${QL_DIR}/shell/*.sh \
&& chmod 777 ${QL_DIR}/docker/*.sh \
&& git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /static \
&& mkdir -p ${QL_DIR}/static \
&& cp -rf /static/* ${QL_DIR}/static \
&& rm -rf /static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules:${PNPM_HOME}/global/5/node_modules \
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://127.0.0.1:5700/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
+2 -2
View File
@@ -12,7 +12,7 @@ import {
} from 'antd';
import { request } from '@/utils/http';
import config from '@/utils/config';
import cron_parser from 'cron-parser';
import { parseExpression } from 'cron-parser';
import isNil from 'lodash/isNil';
const { Option } = Select;
@@ -381,7 +381,7 @@ const SubscriptionModal = ({
if (
scheduleType === 'interval' ||
!value ||
cron_parser.parseExpression(value).hasNext()
parseExpression(value).hasNext()
) {
return Promise.resolve();
} else {
+2 -2
View File
@@ -1,6 +1,6 @@
import intl from 'react-intl-universal';
import { LANG_MAP, LOG_END_SYMBOL } from './const';
import cron_parser from 'cron-parser';
import { parseExpression } from 'cron-parser';
import { ICrontab } from '@/pages/crontab/type';
export default function browserType() {
@@ -333,7 +333,7 @@ export function getCommandScript(
export function parseCrontab(schedule: string): Date | null {
try {
const time = cron_parser.parseExpression(schedule);
const time = parseExpression(schedule);
if (time) {
return time.next().toDate();
}