add docker-in-docker image
This commit is contained in:
parent
74d39bb0a5
commit
0d53de011a
|
|
@ -28,13 +28,20 @@ defaults:
|
|||
|
||||
env:
|
||||
DOCKER_IMAGE_REPO: vegardit/gitea-act-runner
|
||||
DOCKER_IMAGE_TAG: latest
|
||||
TRIVY_CACHE_DIR: ~/.trivy/cache
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- DOCKER_FILE: Dockerfile
|
||||
DOCKER_IMAGE_TAG: latest
|
||||
- DOCKER_FILE: DinD.Dockerfile
|
||||
DOCKER_IMAGE_TAG: dind-latest
|
||||
fail-fast: true
|
||||
steps:
|
||||
- name: Show environment variables
|
||||
run: env | sort
|
||||
|
|
@ -63,6 +70,8 @@ jobs:
|
|||
DOCKER_REGISTRY: docker.io
|
||||
DOCKER_REGISTRY_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
DOCKER_IMAGE_TAG: ${{ matrix.DOCKER_IMAGE_TAG }}
|
||||
DOCKER_FILE: ${{ matrix.DOCKER_FILE }}
|
||||
TRIVY_GITHUB_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
set -eu
|
||||
|
|
@ -74,13 +83,15 @@ jobs:
|
|||
|
||||
- name: Publish Docker image to GH registry
|
||||
if: ${{ github.ref_name == 'main' && github.event_name != 'pull_request' && !env.ACT }} # https://github.com/nektos/act#skipping-steps
|
||||
env:
|
||||
DOCKER_IMAGE_TAG: ${{ matrix.DOCKER_IMAGE_TAG }}
|
||||
run: |
|
||||
set -eux
|
||||
|
||||
echo "${{ github.token }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
docker image tag $DOCKER_IMAGE_REPO ghcr.io/$DOCKER_IMAGE_REPO
|
||||
docker push ghcr.io/$DOCKER_IMAGE_REPO
|
||||
docker image tag $DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG ghcr.io/$DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG
|
||||
docker push ghcr.io/$DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG
|
||||
|
||||
- name: Delete untagged images
|
||||
uses: actions/github-script@v6
|
||||
|
|
|
|||
35
README.md
35
README.md
|
|
@ -24,10 +24,15 @@
|
|||
|
||||
## Usage
|
||||
|
||||
The docker image comes in two flavors:
|
||||
- `vegardit/gitea-act-runner:latest`: only contains the Gitea act_runner and executes workflows in containers of the docker engine running act_runner itself (DooD / Docker-out-of-Docker approach)
|
||||
- `vegardit/gitea-act-runner:dind-latest`: executes workflows using an embedded docker engine (DinD / Docker-in-Docker approach) providing better process isolation
|
||||
|
||||
### Docker Run
|
||||
|
||||
Running from the command line:
|
||||
|
||||
- Docker-out-of-Docker approach
|
||||
```sh
|
||||
docker run \
|
||||
-e GITEA_INSTANCE_URL=https://gitea.example.com \
|
||||
|
|
@ -37,10 +42,21 @@ Running from the command line:
|
|||
vegardit/gitea-act-runner:latest
|
||||
```
|
||||
|
||||
- Docker-in-Docker approach
|
||||
```sh
|
||||
docker run \
|
||||
-e GITEA_INSTANCE_URL=https://gitea.example.com \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<INSERT_TOKEN_HERE> \
|
||||
--privileged
|
||||
--name gitea_act_runner \
|
||||
vegardit/gitea-act-runner:dind-latest
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Example `docker-compose.yml`:
|
||||
|
||||
- Docker-out-of-Docker approach
|
||||
```yaml
|
||||
version: '3.8' # https://docs.docker.com/compose/compose-file/compose-versioning/
|
||||
|
||||
|
|
@ -60,6 +76,25 @@ services:
|
|||
# or: GITEA_RUNNER_REGISTRATION_TOKEN: '<INSERT_TOKEN_HERE>'
|
||||
```
|
||||
|
||||
- Docker-in-Docker approach
|
||||
```yaml
|
||||
version: '3.8' # https://docs.docker.com/compose/compose-file/compose-versioning/
|
||||
|
||||
services:
|
||||
|
||||
gitea_act_runner:
|
||||
image: vegardit/gitea-act-runner:dind-latest
|
||||
privileged: true
|
||||
volumes:
|
||||
- /my/path/to/data/dir:/data:rw # the config file is located at /data/.runner and needs to survive container restarts
|
||||
environment:
|
||||
TZ: "Europe/Berlin"
|
||||
# config parameters for initial runner registration:
|
||||
GITEA_INSTANCE_URL: 'https://gitea.example.com' # required
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN_FILE: 'path/to/file' # one-time registration token, only required on first container start
|
||||
# or: GITEA_RUNNER_REGISTRATION_TOKEN: '<INSERT_TOKEN_HERE>'
|
||||
```
|
||||
|
||||
### Additional environment variables
|
||||
|
||||
The following environment variables can be specified to further configure the service.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ if [[ $OSTYPE == "cygwin" || $OSTYPE == "msys" ]]; then
|
|||
fi
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build "$project_root" \
|
||||
--file "image/Dockerfile" \
|
||||
--file "image/$DOCKER_FILE" \
|
||||
--progress=plain \
|
||||
--pull \
|
||||
--build-arg INSTALL_SUPPORT_TOOLS=${INSTALL_SUPPORT_TOOLS:-0} \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,201 @@
|
|||
#syntax=docker/dockerfile:1.4
|
||||
# see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md
|
||||
# see https://docs.docker.com/engine/reference/builder/#syntax
|
||||
#
|
||||
# SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com)
|
||||
# SPDX-FileContributor: Sebastian Thomschke
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-ArtifactOfProjectHomePage: https://github.com/vegardit/docker-gitea-act-runner
|
||||
#
|
||||
# https://hub.docker.com/_/debian?tab=tags&name=stable-slim
|
||||
|
||||
FROM debian:stable-slim as runtime-base-image
|
||||
|
||||
LABEL maintainer="Vegard IT GmbH (vegardit.com)"
|
||||
|
||||
USER root
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG LC_ALL=C
|
||||
|
||||
ARG INSTALL_SUPPORT_TOOLS=0
|
||||
|
||||
ARG ACT_RUNNER_DOWNLOAD_URL
|
||||
ARG UPX_COMPRESS=true
|
||||
|
||||
ARG BASE_LAYER_CACHE_KEY
|
||||
|
||||
RUN --mount=type=bind,source=.shared,target=/mnt/shared <<EOF
|
||||
|
||||
set -euo pipefail
|
||||
/mnt/shared/cmd/debian-install-os-updates.sh
|
||||
/mnt/shared/cmd/debian-install-support-tools.sh
|
||||
|
||||
function minimize() {
|
||||
ls -l $@
|
||||
echo "Stripping [$@]..."
|
||||
command strip --strip-unneeded $@
|
||||
ls -l $@
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
echo "Compressing [$@]..."
|
||||
/opt/upx/upx -9 $@ || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "#################################################"
|
||||
echo "Installing required packages..."
|
||||
echo "#################################################"
|
||||
apt-get install --no-install-recommends -y binutils ca-certificates curl sudo tini
|
||||
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
echo "#################################################"
|
||||
echo "Downloading UPX..."
|
||||
echo "#################################################"
|
||||
apt-get install --no-install-recommends -y xz-utils
|
||||
mkdir /opt/upx
|
||||
upx_download_url=$(curl -fsSL https://api.github.com/repos/upx/upx/releases/latest | grep browser_download_url | grep amd64_linux.tar.xz | cut "-d\"" -f4)
|
||||
echo "Downloading [$upx_download_url]..."
|
||||
curl -fL $upx_download_url | tar Jxv -C /opt/upx --strip-components=1
|
||||
/opt/upx/upx --version
|
||||
fi
|
||||
|
||||
minimize /usr/bin/tini-static
|
||||
|
||||
echo "#################################################"
|
||||
echo "Downloading Gitea act runner..."
|
||||
echo "#################################################"
|
||||
curl -fsSL $ACT_RUNNER_DOWNLOAD_URL -o /usr/local/bin/act_runner
|
||||
chmod 755 /usr/local/bin/act_runner
|
||||
minimize /usr/local/bin/act_runner
|
||||
act_runner --version
|
||||
|
||||
echo "#################################################"
|
||||
echo "Adding [act] user..."
|
||||
echo "#################################################"
|
||||
addgroup --gid 1000 act
|
||||
adduser --uid 1000 --ingroup act --home /data --shell /bin/bash --disabled-password --gecos "" act
|
||||
adduser act sudo
|
||||
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
echo "#################################################"
|
||||
echo "Installing docker engine..."
|
||||
echo "#################################################"
|
||||
# https://docs.docker.com/engine/install/debian/#install-using-the-repository
|
||||
apt-get install --no-install-recommends -y gnupg
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo \
|
||||
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
|
||||
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" > /etc/apt/sources.list.d/docker.list
|
||||
apt-get update
|
||||
apt-get install --no-install-recommends -y docker-ce docker-ce-cli containerd.io fuse-overlayfs
|
||||
|
||||
minimize /usr/bin/containerd* /usr/bin/ctr /usr/bin/docker* /usr/bin/runc
|
||||
|
||||
docker --version
|
||||
runc --version
|
||||
|
||||
# https://github.com/docker/for-linux/issues/1437#issuecomment-1293818806
|
||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
||||
|
||||
# set up subuid/subgid so that "--userns-remap=default" works out-of-the-box
|
||||
sudo addgroup --system dockremap
|
||||
sudo adduser --system --ingroup dockremap dockremap
|
||||
echo 'dockremap:165536:65536' | sudo tee -a /etc/subuid
|
||||
echo 'dockremap:165536:65536' | sudo tee -a /etc/subgid
|
||||
|
||||
usermod -aG docker act
|
||||
|
||||
apt-get remove -y gnupg
|
||||
|
||||
echo "#################################################"
|
||||
echo "Cleanup..."
|
||||
echo "#################################################"
|
||||
apt-get remove -y binutils curl
|
||||
rm -rf /opt/upx
|
||||
/mnt/shared/cmd/debian-cleanup.sh
|
||||
|
||||
EOF
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG GIT_BRANCH
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_COMMIT_DATE
|
||||
ARG GIT_REPO_URL
|
||||
|
||||
LABEL \
|
||||
org.label-schema.schema-version="1.0" \
|
||||
org.label-schema.build-date=$BUILD_DATE \
|
||||
org.label-schema.vcs-ref=$GIT_COMMIT_HASH \
|
||||
org.label-schema.vcs-url=$GIT_REPO_URL
|
||||
|
||||
# Default configuration: can be overridden at the docker command line
|
||||
ENV \
|
||||
INIT_SH_FILE='' \
|
||||
#
|
||||
GITEA_RUNNER_CONFIG_TEMPLATE_FILE='/opt/config.template.yaml' \
|
||||
#
|
||||
GITEA_RUNNER_NAME='' \
|
||||
GITEA_RUNNER_LABELS='' \
|
||||
GITEA_RUNNER_LABELS_DEFAULT='\
|
||||
ubuntu-latest:docker://catthehacker/ubuntu:runner-22.04,\
|
||||
ubuntu-22.04:docker://catthehacker/ubuntu:runner-22.04,\
|
||||
ubuntu-20.04:docker://catthehacker/ubuntu:runner-20.04' \
|
||||
GITEA_RUNNER_UID=1000 \
|
||||
GITEA_RUNNER_GID=1000 \
|
||||
#
|
||||
GITEA_RUNNER_REGISTRATION_FILE='/data/.runner' \
|
||||
GITEA_RUNNER_REGISTRATION_TIMEOUT=30\
|
||||
GITEA_RUNNER_REGISTRATION_RETRY_INTERVAL=5s \
|
||||
#
|
||||
GITEA_RUNNER_LOG_LEVEL='info' \
|
||||
GITEA_RUNNER_MAX_PARALLEL_JOBS=1 \
|
||||
GITEA_RUNNER_JOB_TIMEOUT='3h' \
|
||||
GITEA_RUNNER_ENV_FILE='/data/.env' \
|
||||
GITEA_RUNNER_FETCH_TIMEOUT='5s' \
|
||||
GITEA_RUNNER_FETCH_INTERVAL='2s' \
|
||||
#
|
||||
GITEA_INSTANCE_INSECURE='false' \
|
||||
#
|
||||
GITEA_RUNNER_JOB_CONTAINER_NETWORK='bridge' \
|
||||
GITEA_RUNNER_JOB_CONTAINER_OPTIONS='' \
|
||||
GITEA_RUNNER_JOB_CONTAINER_PRIVILEGED='false' \
|
||||
GITEA_RUNNER_ACTION_CACHE_DIR='/data/cache/actions' \
|
||||
#
|
||||
ACT_CACHE_SERVER_ENABLED='true' \
|
||||
ACT_CACHE_SERVER_DIR='/data/cache/server' \
|
||||
ACT_CACHE_SERVER_HOST='' \
|
||||
ACT_CACHE_SERVER_PORT=0
|
||||
|
||||
RUN <<EOF
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "#################################################"
|
||||
echo "Writing build_info..."
|
||||
echo "#################################################"
|
||||
echo -e "
|
||||
GIT_REPO: $GIT_REPO_URL
|
||||
GIT_BRANCH: $GIT_BRANCH
|
||||
GIT_COMMIT: $GIT_COMMIT_HASH @ $GIT_COMMIT_DATE
|
||||
IMAGE_BUILD: $BUILD_DATE" >/opt/build_info
|
||||
cat /opt/build_info
|
||||
|
||||
EOF
|
||||
|
||||
COPY image/*.sh /opt/
|
||||
COPY image/config.template.yaml /opt/
|
||||
COPY .shared/lib/bash-init.sh /opt/bash-init.sh
|
||||
|
||||
USER act
|
||||
|
||||
VOLUME /data
|
||||
VOLUME /var/lib/docker
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
|
||||
CMD ["/bin/bash", "/opt/run.sh"]
|
||||
119
image/Dockerfile
119
image/Dockerfile
|
|
@ -9,9 +9,6 @@
|
|||
#
|
||||
# https://hub.docker.com/_/debian?tab=tags&name=stable-slim
|
||||
|
||||
######################
|
||||
# runtime image base
|
||||
######################
|
||||
FROM debian:stable-slim as runtime-base-image
|
||||
|
||||
LABEL maintainer="Vegard IT GmbH (vegardit.com)"
|
||||
|
|
@ -20,20 +17,59 @@ USER root
|
|||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG BASE_LAYER_CACHE_KEY
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG LC_ALL=C
|
||||
|
||||
ARG INSTALL_SUPPORT_TOOLS=0
|
||||
|
||||
ARG ACT_RUNNER_DOWNLOAD_URL
|
||||
ARG UPX_COMPRESS=true
|
||||
|
||||
ARG BASE_LAYER_CACHE_KEY
|
||||
|
||||
RUN --mount=type=bind,source=.shared,target=/mnt/shared <<EOF
|
||||
|
||||
set -euo pipefail
|
||||
/mnt/shared/cmd/debian-install-os-updates.sh
|
||||
/mnt/shared/cmd/debian-install-support-tools.sh
|
||||
|
||||
function minimize() {
|
||||
ls -l $@
|
||||
echo "Stripping [$@]..."
|
||||
command strip --strip-unneeded $@
|
||||
ls -l $@
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
echo "Compressing [$@]..."
|
||||
/opt/upx/upx -9 $@ || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "#################################################"
|
||||
echo "Installing ca-certificates, tini..."
|
||||
echo "Installing required packages..."
|
||||
echo "#################################################"
|
||||
apt-get install --no-install-recommends -y ca-certificates sudo tini
|
||||
apt-get install --no-install-recommends -y binutils ca-certificates curl sudo tini
|
||||
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
echo "#################################################"
|
||||
echo "Downloading UPX..."
|
||||
echo "#################################################"
|
||||
apt-get install --no-install-recommends -y xz-utils
|
||||
mkdir /opt/upx
|
||||
upx_download_url=$(curl -fsSL https://api.github.com/repos/upx/upx/releases/latest | grep browser_download_url | grep amd64_linux.tar.xz | cut "-d\"" -f4)
|
||||
echo "Downloading [$upx_download_url]..."
|
||||
curl -fL $upx_download_url | tar Jxv -C /opt/upx --strip-components=1
|
||||
/opt/upx/upx --version
|
||||
fi
|
||||
|
||||
minimize /usr/bin/tini-static
|
||||
|
||||
echo "#################################################"
|
||||
echo "Downloading Gitea act runner..."
|
||||
echo "#################################################"
|
||||
curl -fsSL $ACT_RUNNER_DOWNLOAD_URL -o /usr/local/bin/act_runner
|
||||
chmod 755 /usr/local/bin/act_runner
|
||||
minimize /usr/local/bin/act_runner
|
||||
act_runner --version
|
||||
|
||||
echo "#################################################"
|
||||
echo "Adding [act] user..."
|
||||
|
|
@ -43,74 +79,15 @@ RUN --mount=type=bind,source=.shared,target=/mnt/shared <<EOF
|
|||
adduser act sudo
|
||||
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
echo "#################################################"
|
||||
echo "Cleanup..."
|
||||
echo "#################################################"
|
||||
apt-get remove -y binutils curl
|
||||
rm -rf /opt/upx
|
||||
/mnt/shared/cmd/debian-cleanup.sh
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
######################
|
||||
# build image
|
||||
######################
|
||||
|
||||
# https://hub.docker.com/_/python?tab=tags&name=3-slim
|
||||
FROM debian:stable-slim AS build-image
|
||||
|
||||
USER root
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG BASE_LAYER_CACHE_KEY
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG LC_ALL=C
|
||||
ARG INSTALL_SUPPORT_TOOLS=0
|
||||
|
||||
ARG ACT_RUNNER_DOWNLOAD_URL
|
||||
ARG UPX_COMPRESS=true
|
||||
|
||||
RUN --mount=type=bind,source=.shared,target=/mnt/shared <<EOF
|
||||
|
||||
set -euo pipefail
|
||||
/mnt/shared/cmd/debian-install-os-updates.sh
|
||||
|
||||
echo "#################################################"
|
||||
echo "Installing tools..."
|
||||
echo "#################################################"
|
||||
apt-get install --no-install-recommends -y binutils ca-certificates curl xz-utils
|
||||
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
echo "#################################################"
|
||||
echo "Downloading UPX..."
|
||||
echo "#################################################"
|
||||
mkdir /opt/upx
|
||||
upx_download_url=$(curl -fsSL https://api.github.com/repos/upx/upx/releases/latest | grep browser_download_url | grep amd64_linux.tar.xz | cut "-d\"" -f4)
|
||||
echo "Downloading [$upx_download_url]..."
|
||||
curl -fL $upx_download_url | tar Jxv -C /opt/upx --strip-components=1
|
||||
/opt/upx/upx --version
|
||||
fi
|
||||
|
||||
echo "#################################################"
|
||||
echo "Downloading Gitea act runner..."
|
||||
echo "#################################################"
|
||||
curl -fsSL $ACT_RUNNER_DOWNLOAD_URL -o /usr/local/bin/act_runner
|
||||
chmod 755 /usr/local/bin/act_runner
|
||||
ls -l /usr/local/bin/act_runner
|
||||
echo "Stripping..."
|
||||
strip --strip-unneeded /usr/local/bin/act_runner
|
||||
ls -l /usr/local/bin/act_runner
|
||||
if [[ $UPX_COMPRESS == "true" ]]; then
|
||||
/opt/upx/upx -9 /usr/local/bin/act_runner
|
||||
fi
|
||||
act_runner --version
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
######################
|
||||
# runtime image
|
||||
######################
|
||||
FROM runtime-base-image
|
||||
COPY --from=build-image /usr/local/bin/act_runner /usr/local/bin/act_runner
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG GIT_BRANCH
|
||||
ARG GIT_COMMIT_HASH
|
||||
|
|
@ -183,7 +160,7 @@ COPY .shared/lib/bash-init.sh /opt/bash-init.sh
|
|||
|
||||
USER act
|
||||
|
||||
VOLUME [ "/data" ]
|
||||
VOLUME /data
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ if [ -n "${GITEA_RUNNER_GID:-}" ]; then
|
|||
fi
|
||||
sudo chown -R act:act /data
|
||||
|
||||
if [[ -f /usr/bin/dockerd ]]; then
|
||||
log INFO "Starting docker engine..."
|
||||
sudo service docker start
|
||||
while [[ ! -e /var/run/docker.sock ]]; do sleep 2; done
|
||||
fi
|
||||
|
||||
docker_group=$(stat -c '%G' /var/run/docker.sock)
|
||||
if [[ $docker_group == "UNKNOWN" ]]; then
|
||||
docker_gid=$(stat -c '%g' /var/run/docker.sock)
|
||||
|
|
|
|||
Loading…
Reference in New Issue