Compare commits

..

36 Commits

Author SHA1 Message Date
Ethan Chiu
abfc04c58a Download action repos into directory 2020-08-11 16:31:15 -04:00
Ethan Chiu
46245a1a71 Resolve Template Error by Adding ExpressionFunctions 2020-08-03 16:30:37 -04:00
Ethan Chiu
45345dc981 testing... 2020-07-31 15:30:48 -04:00
Christopher Johnson
7b608e3e92 Adding help text for the new runnergroup feature (#626)
Co-authored-by: Christopher Johnson <thchrisjohnson@github.com>
2020-07-30 12:03:40 -04:00
Ethan Chiu
f028b4e2b0 Revert JobSteps to Queue Data Structure (#625)
* Revert JobSteps to Queue data structure

* Revert tests
2020-07-29 16:19:04 -04:00
TingluoHuang
38f816c2ae prepare release 2.272.0 runner. 2020-07-29 15:31:45 -04:00
efyx
bc1fe2cfe0 Fix poor performance of process spawned from svc daemon (#614) 2020-07-29 15:20:28 -04:00
Ethan Chiu
89a13db2c3 Remove TESTING_COMPOSITE_ACTIONS_ALPHA Env Variable (#624) 2020-07-29 15:12:15 -04:00
Ethan Chiu
d59092d973 GITHUB_ACTION_PATH + GITHUB_ACTION so that we can run scripts for Composite Run Steps (#615)
* Add environment variable for GITHUB_ACTION_PATH

* ah

* Remove debugging messages

* Set github action path at step level instead of global scope to avoid necessary removal

* Remove set context for github action

* Set github action path before and after composite action

* Copy GitHub Context, use this copied context for each composit step, and then set the action_path for each one (to avoid stamping over parent pointer GitHubContext
2020-07-29 14:28:14 -04:00
Ethan Chiu
7ab3d5ad42 progress... 2020-07-28 17:29:43 -04:00
Ethan Chiu
4c02d0a685 new function for inputs within a composite action 2020-07-28 10:36:00 -04:00
Ethan Chiu
855b90c3d4 Explicitly define what is allowed for a composite action (#605)
* Explicitly define what is allowed for an action

* Add step-env

* Remove secrets + defaults

* new line

* Add safety check to prevent from checking defaults in ScriptHandler for composite action

* Revert "Add safety check to prevent from checking defaults in ScriptHandler for composite action"

This reverts commit aeae15de7b.

* Need to explictly use ActionStep type since we need the .Inputs attribute which is only found in the ActionStep not IStep

* Fix ActionManifestManager

* Remove todos

* Revert "Revert "Add safety check to prevent from checking defaults in ScriptHandler for composite action""

This reverts commit a22fcbc036.

* revert

* Remove needs in env

* Make shell required + add inputs

* Remove passing context to all composite steps attribuyte
2020-07-28 10:15:46 -04:00
Ethan Chiu
3d36af47f1 Experimentation with evaluating inputs in the context 2020-07-27 17:45:20 -04:00
Ethan Chiu
992ce4b924 add new changes 2020-07-27 14:17:30 -04:00
Ethan Chiu
e927bacf3c revert 2020-07-27 14:17:01 -04:00
Ethan Chiu
1ce75f188b Merge branch 'main' of https://github.com/actions/runner into compositeActionProofOfConcept 2020-07-27 14:09:12 -04:00
Ethan Chiu
e0d4270cc1 Remove passing context to all composite steps attribuyte 2020-07-27 13:04:33 -04:00
Ethan Chiu
49893b6ede Merge branch 'main' of https://github.com/actions/runner into users/ethanchewy/compositeRestrictUnknownBehavior 2020-07-27 12:45:45 -04:00
Ethan Chiu
6a46ef1c47 Make shell required + add inputs 2020-07-27 12:32:32 -04:00
Christopher Johnson
48ac96307c Add ability to register a runner to the non-default self-hosted runner group (#613)
Co-authored-by: Christopher Johnson <thchrisjohnson@github.com>
2020-07-23 17:46:48 -04:00
Ethan Chiu
80540edd4e Fix templating errors 2020-07-23 13:01:09 -04:00
Ethan Chiu
cc8e2738ef Add 'uses' and 'with' to action yaml and change names to be consistent with workflow yaml 2020-07-23 12:22:38 -04:00
Ethan Chiu
e9dcc05d75 Merge branch 'users/ethanchewy/compositeRestrictUnknownBehavior' of https://github.com/actions/runner into compositeActionProofOfConcept 2020-07-23 12:17:08 -04:00
Ethan Chiu
2e50dffb37 Clean Up Composite UI (#610)
* Remove redundant code (display name is already evaluated in ActionRunner beforehand for each step)

* remove

* Remove nesting information for composite steps.

* put messages in debug logs if composite. if not, put these messages as outputs

* Fix group issue

* Fix end group issue
2020-07-23 09:45:00 -04:00
Ethan Chiu
a24e33bbcc Remove needs in env 2020-07-22 12:48:52 -04:00
Ethan Chiu
5dfb2cc552 revert 2020-07-21 17:55:34 -04:00
Ethan Chiu
143266bc96 Revert "Revert "Add safety check to prevent from checking defaults in ScriptHandler for composite action""
This reverts commit a22fcbc036.
2020-07-21 17:53:29 -04:00
Ethan Chiu
522fbd0546 Remove todos 2020-07-21 17:46:51 -04:00
Ethan Chiu
2bfa135739 Fix ActionManifestManager 2020-07-21 17:46:09 -04:00
Ethan Chiu
3381b951a0 Need to explictly use ActionStep type since we need the .Inputs attribute which is only found in the ActionStep not IStep 2020-07-21 17:36:40 -04:00
Ethan Chiu
a22fcbc036 Revert "Add safety check to prevent from checking defaults in ScriptHandler for composite action"
This reverts commit aeae15de7b.
2020-07-21 14:45:58 -04:00
Ethan Chiu
aeae15de7b Add safety check to prevent from checking defaults in ScriptHandler for composite action 2020-07-21 14:33:58 -04:00
Ethan Chiu
6602117989 new line 2020-07-21 13:11:46 -04:00
Ethan Chiu
89412f35bf Remove secrets + defaults 2020-07-21 11:23:25 -04:00
Ethan Chiu
220793d4e9 Add step-env 2020-07-20 17:46:02 -04:00
Ethan Chiu
645ba099b9 Explicitly define what is allowed for an action 2020-07-20 17:41:57 -04:00
49 changed files with 460 additions and 1388 deletions

View File

@@ -18,12 +18,28 @@ jobs:
build:
strategy:
matrix:
runtime: [ linux-x64 ]
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
include:
- runtime: linux-x64
os: ubuntu-latest
devScript: ./dev.sh
- runtime: linux-arm64
os: ubuntu-latest
devScript: ./dev.sh
- runtime: linux-arm
os: ubuntu-latest
devScript: ./dev.sh
- runtime: osx-x64
os: macOS-latest
devScript: ./dev.sh
- runtime: win-x64
os: windows-latest
devScript: ./dev
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
@@ -34,6 +50,13 @@ jobs:
${{ matrix.devScript }} layout Release ${{ matrix.runtime }}
working-directory: src
# Run tests
- name: L0
run: |
${{ matrix.devScript }} test
working-directory: src
if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm'
# Create runner package tar.gz/zip
- name: Package Release
if: github.event_name != 'pull_request'
@@ -48,18 +71,3 @@ jobs:
with:
name: runner-package-${{ matrix.runtime }}
path: _package
- name: Build old version
run: |
echo 2.270.0 > runnerversion
${{ matrix.devScript }} layout Release ${{ matrix.runtime }}
${{ matrix.devScript }} package Release
working-directory: src
# Upload runner package tar.gz/zip as artifact
- name: Publish Artifact old
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v1
with:
name: runner-package-${{ matrix.runtime }}-old
path: _package

View File

@@ -1,6 +1,7 @@
name: Runner CD
on:
workflow_dispatch:
push:
paths:
- releaseVersion

View File

@@ -1,57 +0,0 @@
FROM mcr.microsoft.com/dotnet/core/runtime-deps:3.1-buster-slim
ENV RUNNER_CONFIG_URL=""
ENV GITHUB_PAT=""
ENV RUNNER_NAME=""
ENV RUNNER_GROUP=""
ENV RUNNER_LABELS=""
# ENV GITHUB_RUNNER_SCOPE=""
# ENV GITHUB_SERVER_URL=""
# ENV GITHUB_API_URL=""
# ENV K8S_HOST_IP=""
RUN apt-get update --fix-missing \
&& apt-get install -y --no-install-recommends \
curl \
jq \
apt-utils \
apt-transport-https \
unzip \
net-tools\
gnupg2\
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install kubectl
RUN curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list && \
apt-get update && apt-get -y install --no-install-recommends kubectl
# Install docker
RUN curl -fsSL https://get.docker.com -o get-docker.sh
RUN sh get-docker.sh
# Allow runner to run as root
ENV RUNNER_ALLOW_RUNASROOT=1
# Directory for runner to operate in
RUN mkdir /actions-runner
WORKDIR /actions-runner
COPY ./src/Misc/download-runner.sh /actions-runner/download-runner.sh
COPY ./src/Misc/entrypoint.sh /actions-runner/entrypoint.sh
# COPY ./src/Misc/jobstart.sh /actions-runner/jobstart.sh
# COPY ./src/Misc/jobrunning.sh /actions-runner/jobrunning.sh
# COPY ./src/Misc/jobcomplete.sh /actions-runner/jobcomplete.sh
COPY ./src/Misc/runner_lifecycle.sh /actions-runner/runner_lifecycle.sh
RUN /actions-runner/download-runner.sh
RUN rm -f /actions-runner/download-runner.sh
# ENV _INTERNAL_JOBSTART_NOTIFICATION=/actions-runner/jobstart.sh
# ENV _INTERNAL_JOBRUNNING_NOTIFICATION=/actions-runner/jobrunning.sh
# ENV _INTERNAL_JOBCOMPLETE_NOTIFICATION=/actions-runner/jobcomplete.sh
ENV _INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION=/actions-runner/runner_lifecycle.sh
ENTRYPOINT ["./entrypoint.sh"]

View File

@@ -1,46 +0,0 @@
FROM docker:19.03
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
RUN set -eux; \
apk add --no-cache \
btrfs-progs \
e2fsprogs \
e2fsprogs-extra \
iptables \
openssl \
shadow-uidmap \
xfsprogs \
xz \
# pigz: https://github.com/moby/moby/pull/35697 (faster gzip implementation)
pigz \
; \
# only install zfs if it's available for the current architecture
# https://git.alpinelinux.org/cgit/aports/tree/main/zfs/APKBUILD?h=3.6-stable#n9 ("all !armhf !ppc64le" as of 2017-11-01)
# "apk info XYZ" exits with a zero exit code but no output when the package exists but not for this arch
if zfs="$(apk info --no-cache --quiet zfs)" && [ -n "$zfs" ]; then \
apk add --no-cache zfs; \
fi
# TODO aufs-tools
# set up subuid/subgid so that "--userns-remap=default" works out-of-the-box
RUN set -x \
&& addgroup -S dockremap \
&& adduser -S -G dockremap dockremap \
&& echo 'dockremap:165536:65536' >> /etc/subuid \
&& echo 'dockremap:165536:65536' >> /etc/subgid
# https://github.com/docker/docker/tree/master/hack/dind
ENV DIND_COMMIT ed89041433a031cafc0a0f19cfe573c31688d377
RUN set -eux; \
wget -O /usr/local/bin/dind "https://raw.githubusercontent.com/docker/docker/${DIND_COMMIT}/hack/dind"; \
chmod +x /usr/local/bin/dind
COPY dockerd-entrypoint.sh /usr/local/bin/
VOLUME /var/lib/docker
EXPOSE 6788 6789
ENTRYPOINT ["dockerd-entrypoint.sh"]
CMD []

View File

@@ -1,14 +0,0 @@
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: auto-scale-runners
spec:
replicas: 1
maxRunnerLimit: 5
template:
spec:
configURL: https://github.com/bbq-beets/ting-test
githubTokenSecretKeyRef:
name: githubtoken
key: GITHUB_PAT

View File

@@ -1,63 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: runner-pod
labels:
name: runner-pod
spec:
containers:
- name: runner-pod
image: huangtingluo/autoscale-runner:v0.0
imagePullPolicy: Always
env:
- name: GITHUB_PAT
value: 62c13e14e947958516c103a9584f66227697c447
- name: GITHUB_RUNNER_SCOPE
value: monalisa/main123
- name: K8S_HOST_IP
value: "192.168.120.1"
# apiVersion: apps/v1
# kind: Deployment
# metadata:
# name: runner-deployment
# spec:
# replicas: 1
# selector:
# matchLabels:
# app: runners
# template:
# metadata:
# labels:
# app: runners
# spec:
# # hostNetwork: true
# # volumes:
# # - name: docker-storage
# # emptyDir: {}
# # containers:
# # - name: docker-host
# # image: docker:18.05-dind
# # imagePullPolicy: Always
# # securityContext:
# # privileged: true
# # volumeMounts:
# # - name: docker-storage
# # mountPath: /var/lib/docker
# # hostNetwork: true
# containers:
# - name: runner
# image: huangtingluo/autoscale-runner:v0.0
# imagePullPolicy: Always
# env:
# - name: GITHUB_PAT
# value: 62c13e14e947958516c103a9584f66227697c447
# - name: GITHUB_RUNNER_SCOPE
# value: monalisa/main123
# - name: K8S_HOST_IP
# value: "192.168.120.1"
# resources:
# limits:
# memory: "128Mi"
# cpu: "500m"

View File

@@ -1,186 +0,0 @@
#!/bin/sh
set -eu
_tls_ensure_private() {
local f="$1"; shift
[ -s "$f" ] || openssl genrsa -out "$f" 4096
}
_tls_san() {
{
ip -oneline address | awk '{ gsub(/\/.+$/, "", $4); print "IP:" $4 }'
{
cat /etc/hostname
echo 'docker'
echo 'localhost'
hostname -f
hostname -s
} | sed 's/^/DNS:/'
[ -z "${DOCKER_TLS_SAN:-}" ] || echo "$DOCKER_TLS_SAN"
} | sort -u | xargs printf '%s,' | sed "s/,\$//"
}
_tls_generate_certs() {
local dir="$1"; shift
# if ca/key.pem || !ca/cert.pem, generate CA public if necessary
# if ca/key.pem, generate server public
# if ca/key.pem, generate client public
# (regenerating public certs every startup to account for SAN/IP changes and/or expiration)
# https://github.com/FiloSottile/mkcert/issues/174
local certValidDays='825'
if [ -s "$dir/ca/key.pem" ] || [ ! -s "$dir/ca/cert.pem" ]; then
# if we either have a CA private key or do *not* have a CA public key, then we should create/manage the CA
mkdir -p "$dir/ca"
_tls_ensure_private "$dir/ca/key.pem"
openssl req -new -key "$dir/ca/key.pem" \
-out "$dir/ca/cert.pem" \
-subj '/CN=docker:dind CA' -x509 -days "$certValidDays"
fi
if [ -s "$dir/ca/key.pem" ]; then
# if we have a CA private key, we should create/manage a server key
mkdir -p "$dir/server"
_tls_ensure_private "$dir/server/key.pem"
openssl req -new -key "$dir/server/key.pem" \
-out "$dir/server/csr.pem" \
-subj '/CN=docker:dind server'
cat > "$dir/server/openssl.cnf" <<-EOF
[ x509_exts ]
subjectAltName = $(_tls_san)
EOF
openssl x509 -req \
-in "$dir/server/csr.pem" \
-CA "$dir/ca/cert.pem" \
-CAkey "$dir/ca/key.pem" \
-CAcreateserial \
-out "$dir/server/cert.pem" \
-days "$certValidDays" \
-extfile "$dir/server/openssl.cnf" \
-extensions x509_exts
cp "$dir/ca/cert.pem" "$dir/server/ca.pem"
openssl verify -CAfile "$dir/server/ca.pem" "$dir/server/cert.pem"
fi
if [ -s "$dir/ca/key.pem" ]; then
# if we have a CA private key, we should create/manage a client key
mkdir -p "$dir/client"
_tls_ensure_private "$dir/client/key.pem"
chmod 0644 "$dir/client/key.pem" # openssl defaults to 0600 for the private key, but this one needs to be shared with arbitrary client contexts
openssl req -new \
-key "$dir/client/key.pem" \
-out "$dir/client/csr.pem" \
-subj '/CN=docker:dind client'
cat > "$dir/client/openssl.cnf" <<-'EOF'
[ x509_exts ]
extendedKeyUsage = clientAuth
EOF
openssl x509 -req \
-in "$dir/client/csr.pem" \
-CA "$dir/ca/cert.pem" \
-CAkey "$dir/ca/key.pem" \
-CAcreateserial \
-out "$dir/client/cert.pem" \
-days "$certValidDays" \
-extfile "$dir/client/openssl.cnf" \
-extensions x509_exts
cp "$dir/ca/cert.pem" "$dir/client/ca.pem"
openssl verify -CAfile "$dir/client/ca.pem" "$dir/client/cert.pem"
fi
}
# no arguments passed
# or first arg is `-f` or `--some-option`
if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then
# set "dockerSocket" to the default "--host" *unix socket* value (for both standard or rootless)
uid="$(id -u)"
if [ "$uid" = '0' ]; then
dockerSocket='unix:///var/run/docker.sock'
else
# if we're not root, we must be trying to run rootless
: "${XDG_RUNTIME_DIR:=/run/user/$uid}"
dockerSocket="unix://$XDG_RUNTIME_DIR/docker.sock"
fi
case "${DOCKER_HOST:-}" in
unix://*)
dockerSocket="$DOCKER_HOST"
;;
esac
# add our default arguments
if [ -n "${DOCKER_TLS_CERTDIR:-}" ] \
&& _tls_generate_certs "$DOCKER_TLS_CERTDIR" \
&& [ -s "$DOCKER_TLS_CERTDIR/server/ca.pem" ] \
&& [ -s "$DOCKER_TLS_CERTDIR/server/cert.pem" ] \
&& [ -s "$DOCKER_TLS_CERTDIR/server/key.pem" ] \
; then
# generate certs and use TLS if requested/possible (default in 19.03+)
set -- dockerd \
--host="$dockerSocket" \
--host=tcp://0.0.0.0:6789 \
--tlsverify \
--tlscacert "$DOCKER_TLS_CERTDIR/server/ca.pem" \
--tlscert "$DOCKER_TLS_CERTDIR/server/cert.pem" \
--tlskey "$DOCKER_TLS_CERTDIR/server/key.pem" \
"$@"
DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="${DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS:-} -p 0.0.0.0:6789:6789/tcp"
else
# TLS disabled (-e DOCKER_TLS_CERTDIR='') or missing certs
set -- dockerd \
--host="$dockerSocket" \
--host=tcp://0.0.0.0:6788 \
"$@"
DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="${DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS:-} -p 0.0.0.0:6788:6788/tcp"
fi
fi
if [ "$1" = 'dockerd' ]; then
# explicitly remove Docker's default PID file to ensure that it can start properly if it was stopped uncleanly (and thus didn't clean up the PID file)
find /run /var/run -iname 'docker*.pid' -delete || :
uid="$(id -u)"
if [ "$uid" != '0' ]; then
# if we're not root, we must be trying to run rootless
if ! command -v rootlesskit > /dev/null; then
echo >&2 "error: attempting to run rootless dockerd but missing 'rootlesskit' (perhaps the 'docker:dind-rootless' image variant is intended?)"
exit 1
fi
user="$(id -un 2>/dev/null || :)"
if ! grep -qE "^($uid${user:+|$user}):" /etc/subuid || ! grep -qE "^($uid${user:+|$user}):" /etc/subgid; then
echo >&2 "error: attempting to run rootless dockerd but missing necessary entries in /etc/subuid and/or /etc/subgid for $uid"
exit 1
fi
: "${XDG_RUNTIME_DIR:=/run/user/$uid}"
export XDG_RUNTIME_DIR
if ! mkdir -p "$XDG_RUNTIME_DIR" || [ ! -w "$XDG_RUNTIME_DIR" ] || ! mkdir -p "$HOME/.local/share/docker" || [ ! -w "$HOME/.local/share/docker" ]; then
echo >&2 "error: attempting to run rootless dockerd but need writable HOME ($HOME) and XDG_RUNTIME_DIR ($XDG_RUNTIME_DIR) for user $uid"
exit 1
fi
if [ -f /proc/sys/kernel/unprivileged_userns_clone ] && unprivClone="$(cat /proc/sys/kernel/unprivileged_userns_clone)" && [ "$unprivClone" != '1' ]; then
echo >&2 "error: attempting to run rootless dockerd but need 'kernel.unprivileged_userns_clone' (/proc/sys/kernel/unprivileged_userns_clone) set to 1"
exit 1
fi
if [ -f /proc/sys/user/max_user_namespaces ] && maxUserns="$(cat /proc/sys/user/max_user_namespaces)" && [ "$maxUserns" = '0' ]; then
echo >&2 "error: attempting to run rootless dockerd but need 'user.max_user_namespaces' (/proc/sys/user/max_user_namespaces) set to a sufficiently large value"
exit 1
fi
# TODO overlay support detection?
exec rootlesskit \
--net="${DOCKERD_ROOTLESS_ROOTLESSKIT_NET:-vpnkit}" \
--mtu="${DOCKERD_ROOTLESS_ROOTLESSKIT_MTU:-1500}" \
--disable-host-loopback \
--port-driver=builtin \
--copy-up=/etc \
--copy-up=/run \
${DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS:-} \
"$@"
elif [ -x '/usr/local/bin/dind' ]; then
# if we have the (mostly defunct now) Docker-in-Docker wrapper script, use it
set -- '/usr/local/bin/dind' "$@"
fi
else
# if it isn't `dockerd` we're trying to run, pass it through `docker-entrypoint.sh` so it gets `DOCKER_HOST` set appropriately too
set -- docker-entrypoint.sh "$@"
fi
exec "$@"

View File

@@ -1,48 +0,0 @@
apiVersion: batch.github.actions/v1
kind: CronJob
metadata:
name: cronjob-sample
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
hostNetwork: true
containers:
- name: k8srunner
image: huangtingluo/autoscale-runner:v0.0
imagePullPolicy: Always
env:
- name: GITHUB_PAT
value: 62c13e14e947958516c103a9584f66227697c447
- name: GITHUB_RUNNER_SCOPE
value: monalisa/main123
restartPolicy: Never
# spec:
# containers:
# - name: hello
# image: busybox
# args:
# - /bin/sh
# - -c
# - date; echo Hello from the Kubernetes cluster
# restartPolicy: Never
# jobTemplate:
# spec:
# template:
# spec:
# hostNetwork: true
# containers:
# - name: k8srunner
# image: huangtingluo/autoscale-runner:v0.0
# imagePullPolicy: Always
# env:
# - name: GITHUB_PAT
# value: 62c13e14e947958516c103a9584f66227697c447
# - name: GITHUB_RUNNER_SCOPE
# value: monalisa/main123
# restartPolicy: Never
# backoffLimit: 1
# completions: 0
# parallelism: 3

View File

@@ -1,56 +0,0 @@
apiVersion: v1
items:
- apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: "2020-08-05T19:14:04Z"
name: runner-deployment
namespace: default
resourceVersion: "167447"
selfLink: /apis/autoscaling/v2beta2/namespaces/default/horizontalpodautoscalers/runner-deployment
uid: 54d86943-eca9-468c-9698-c843f6b6183a
spec:
maxReplicas: 10
metrics:
- type: Object
object:
metric:
name: test-metric
describedObject:
apiVersion: v1
kind: Service
name: kubernetes
target:
type: Value
value: 300m
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: runner-deployment
status:
conditions:
- lastTransitionTime: "2020-08-05T19:14:19Z"
message: the HPA controller was able to get the target's current scale
reason: SucceededGetScale
status: "True"
type: AbleToScale
- lastTransitionTime: "2020-08-05T19:14:19Z"
message: 'the HPA was unable to compute the replica count: unable to get metrics
for resource cpu: no metrics returned from resource metrics API'
reason: FailedGetResourceMetric
status: "False"
type: ScalingActive
currentMetrics: null
currentReplicas: 1
desiredReplicas: 0
kind: List
metadata:
resourceVersion: ""
selfLink: ""

View File

@@ -1,92 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-admin
namespace: default
rules:
- apiGroups: [ "" ]
resources: [ "pods", "pods/ephemeralcontainers", "pods/log", "pods/attach", "pods/exec"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: default-pod-admin
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-admin
subjects:
- kind: ServiceAccount
name: default
namespace: default
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: default
name: actions-runners
spec:
template:
spec:
# hostNetwork: true
volumes:
- name: docker-storage
emptyDir: {}
- name: runner-working
emptyDir: {}
containers:
- name: docker-host
image: docker:18.05-dind
imagePullPolicy: Always
securityContext:
privileged: true
volumeMounts:
- name: docker-storage
mountPath: /var/lib/docker
- mountPath: /actions-runner/_work
name: runner-working
- name: k8srunner
image: huangtingluo/autoscale-runner:v0.0
volumeMounts:
- mountPath: /actions-runner/_work
name: runner-working
imagePullPolicy: Always
env:
- name: GITHUB_PAT
value: 62c13e14e947958516c103a9584f66227697c447
- name: GITHUB_RUNNER_SCOPE
value: monalisa/main123
- name: K8S_HOST_IP
value: "192.168.120.1"
- name: DOCKER_HOST
value: tcp://localhost:2375
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: K8S_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: K8S_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: K8S_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: K8S_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
backoffLimit: 1
completions: 20
parallelism: 3

View File

@@ -1,34 +0,0 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-patcher
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: default-pod-patcher
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-patcher
subjects:
- kind: ServiceAccount
name: default
namespace: default
---
apiVersion: v1
kind: Secret
metadata:
name: githubtoken
type: Opaque
stringData:
GITHUB_PAT: "xxx"

View File

@@ -1,18 +1,15 @@
## Features
- Resolve action download info from server (#508, #515, #550)
- Print runner and machine name to log. (#539)
- Composite Actions Support for Multiple Run Steps (#549, #557, #564, #568, #569, #578, #591, #599, #605, #609, #610, #615, #624)
- Prepare to switch GITHUB_ACTION to use ContextName instead of refname (#593)
- Fold logs for intermediate docker commands (#608)
- Add ability to register a runner to the non-default self-hosted runner group (#613)
## Bugs
- Reduce input validation warnings (#506)
- Fix null ref exception in SecretMasker caused by `hashfiles` timeout. (#516)
- Add libicu66 to `./installDependencies.sh` for Ubuntu 20.04 (#535)
- Fix DataContract with Token service (#532)
- Skip search $PATH on command with fully qualified path (#526)
- Restore SELinux context on service file when SELinux is enabled (#525)
- Double quotes around variable so CD works if path contains spaces (#602)
- Bump lodash in /src/Misc/expressionFunc/hashFiles (#603)
- Fix poor performance of process spawned from svc daemon (#614)
## Misc
- Remove SPS/Token migration code. Remove GHES url manipulate code. (#513)
- Add sub-step for developer flow for clarity (#523)
- Update Links and Language to Git + VSCode (#522)
- Update runner configuration exception message (#540)
- Move shared ExecutionContext properties under .Global (#594)
## Windows x64
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows.

View File

@@ -1,12 +0,0 @@
apiVersion: actions.github.com/v1alpha1
kind: Runner
metadata:
name: auto-scale-runners
spec:
organization: monalisa
group: default
repository: main123
githubAdminToken: 62c13e14e947958516c103a9584f66227697c447
env:
- name: K8S_HOST_IP
value: "192.168.120.1"

View File

@@ -1,46 +0,0 @@
apiVersion: actions.github.com/v1alpha1
kind: AutoScaleRunner
metadata:
name: auto-scale-runners
spec:
minReplicas: 1
maxReplicas: 5
configURL: https://github.com/TingluoHuang/example-services
githubTokenSecretKeyRef:
name: githubtoken
key: GITHUB_PAT
template:
spec:
setupDockerInDocker: true
imagePullPolicy: Always
runnerUpdateHandler:
containers:
- name: update-image
image: huangtingluo/workflow_dispatch:latest
imagePullPolicy: Always
env:
- name: GITHUB_TOKEN
valueFrom:
secretKeyRef:
name: githubtoken
key: GITHUB_PAT
- name: GITHUB_OWNER
value: tingluohuang
- name: GITHUB_REPO
value: "workflow_dispatch"
- name: GITHUB_EXTRA_CURL_ARG
value: "-v"
- name: GITHUB_WORKFLOW
value: "2539181"
- name: GITHUB_WORKFLOW_INPUTS
value: "{\"test_input\":\"test\"}"
# - name: GITHUB_REPO
# value: "k8s-runner-image"
# - name: GITHUB_EXTRA_CURL_ARG
# value: "-v"
# - name: GITHUB_WORKFLOW
# value: "docker-publish.yml"
# - name: GITHUB_WORKFLOW_INPUTS
# value: "{\"runnerDownloadUrl\":\"https://github.com/TingluoHuang/runner/releases/download/test/actions-runner-linux-x64-2.299.0.tar.gz\"}"

View File

@@ -1,18 +0,0 @@
#!/bin/bash
set -e
# if the scope has a slash, it's a repo runner
# orgs_or_repos="orgs"
# if [[ "$GITHUB_RUNNER_SCOPE" == *\/* ]]; then
# orgs_or_repos="repos"
# fi
#RUNNER_DOWNLOAD_URL=$(curl -s -X GET ${GITHUB_API_URL}/${orgs_or_repos}/${GITHUB_RUNNER_SCOPE}/actions/runners/downloads -H "authorization: token $GITHUB_PAT" -H "accept: application/vnd.github.everest-preview+json" | jq -r '.[]|select(.os=="linux" and .architecture=="x64")|.download_url')
# download actions and unzip it
#curl -Ls ${RUNNER_DOWNLOAD_URL} | tar xz \
curl -Ls https://github.com/TingluoHuang/runner/releases/download/test/actions-runner-linux-x64-2.299.0.tar.gz | tar xz
# delete the download tar.gz file
rm -f ${RUNNER_DOWNLOAD_URL##*/}

View File

@@ -1,77 +0,0 @@
#!/bin/bash
set -euo pipefail
function fatal() {
echo "error: $1" >&2
exit 1
}
[ -n "${GITHUB_PAT:-""}" ] || fatal "GITHUB_PAT variable must be set"
[ -n "${RUNNER_CONFIG_URL:-""}" ] || fatal "RUNNER_CONFIG_URL variable must be set"
[ -n "${RUNNER_NAME:-""}" ] || fatal "RUNNER_NAME variable must be set"
# if [ -n "${RUNNER_NAME}" ]; then
# # Use container id to gen unique runner name if name not provide
# CONTAINER_ID=$(cat /proc/self/cgroup | head -n 1 | tr '/' '\n' | tail -1 | cut -c1-12)
# RUNNER_NAME="actions-runner-${CONTAINER_ID}"
# fi
# if the scope has a slash, it's a repo runner
# orgs_or_repos="orgs"
# if [[ "$GITHUB_RUNNER_SCOPE" == *\/* ]]; then
# orgs_or_repos="repos"
# fi
# RUNNER_REG_URL="${GITHUB_SERVER_URL:=https://github.com}/${GITHUB_RUNNER_SCOPE}"
echo "Runner Name : ${RUNNER_NAME}"
echo "Registration URL : ${RUNNER_CONFIG_URL}"
# echo "GitHub API URL : ${GITHUB_API_URL:=https://api.github.com}"
echo "Runner Labels : ${RUNNER_LABELS:=""}"
# TODO: if api url is not default, validate it ends in /api/v3
RUNNER_LABELS_ARG=""
if [ -n "${RUNNER_LABELS}" ]; then
RUNNER_LABELS_ARG="--labels ${RUNNER_LABELS}"
fi
RUNNER_GROUP_ARG=""
if [ -n "${RUNNER_GROUP}" ]; then
RUNNER_GROUP_ARG="--runnergroup ${RUNNER_GROUP}"
fi
# if [ -n "${K8S_HOST_IP}" ]; then
# export http_proxy=http://$K8S_HOST_IP:9090
# fi
# curl -v -s -X POST ${GITHUB_API_URL}/${orgs_or_repos}/${GITHUB_RUNNER_SCOPE}/actions/runners/registration-token -H "authorization: token $GITHUB_PAT" -H "accept: application/vnd.github.everest-preview+json"
# Generate registration token
# RUNNER_REG_TOKEN=$(curl -s -X POST ${GITHUB_API_URL}/${orgs_or_repos}/${GITHUB_RUNNER_SCOPE}/actions/runners/registration-token -H "authorization: token $GITHUB_PAT" -H "accept: application/vnd.github.everest-preview+json" | jq -r '.token')
# Create the runner and configure it
./config.sh --unattended --name $RUNNER_NAME --url $RUNNER_CONFIG_URL --pat $GITHUB_PAT $RUNNER_LABELS_ARG $RUNNER_GROUP_ARG --replace --ephemeral
# while (! docker version ); do
# # Docker takes a few seconds to initialize
# echo "Waiting for Docker to launch..."
# sleep 1
# done
# unset env
unset RUNNER_CONFIG_URL
unset GITHUB_PAT
unset RUNNER_NAME
unset RUNNER_GROUP
unset RUNNER_LABELS
unset RUNNER_LABELS_ARG
unset RUNNER_GROUP_ARG
# Run it
./bin/runsvc.sh interactive
# export http_proxy=""
# dockerdpid=$(kubectl exec $K8S_POD_NAME --container docker-host -- pidof dockerd)
# kubectl exec $K8S_POD_NAME --container docker-host -- kill -SIGINT $dockerdpid

View File

@@ -1,25 +0,0 @@
#!/bin/bash
echo "Test-0"
set -euo pipefail
echo "Test-1"
function fatal() {
echo "error: $1" >&2
exit 1
}
echo "Test-2"
[ -n "${K8S_POD_NAME:-""}" ] || fatal "K8S_POD_NAME variable must be set"
echo "Test-3"
# echo $http_proxy
# unset http_proxy
# unset https_proxy
# export http_proxy=
# export HTTP_PROXY=
echo "Test-4"
kubectl annotate pods $K8S_POD_NAME JOBCOMPLETE=$(date +%s) || fatal "Can't annotate job complete"
echo "Test-5"
exit 0

View File

@@ -1,25 +0,0 @@
#!/bin/bash
echo "Test-0"
set -euo pipefail
echo "Test-1"
function fatal() {
echo "error: $1" >&2
exit 1
}
echo "Test-2"
[ -n "${K8S_POD_NAME:-""}" ] || fatal "K8S_POD_NAME variable must be set"
echo "Test-3"
# echo $http_proxy
# unset http_proxy
# unset https_proxy
# export http_proxy=
# export HTTP_PROXY=
echo "Test-4"
kubectl annotate pods $K8S_POD_NAME JOBRUNNING=$(date +%s) --overwrite || fatal "Can't annotate job running"
echo "Test-5"
exit 0

View File

@@ -1,32 +0,0 @@
#!/bin/bash
echo "Test-0"
set -euo pipefail
echo "Test-1"
function fatal() {
echo "error: $1" >&2
exit 1
}
echo "Test-2"
[ -n "${K8S_POD_NAME:-""}" ] || fatal "K8S_POD_NAME variable must be set"
echo "Test-3"
# echo $http_proxy
# # unset http_proxy
# # unset https_proxy
# export http_proxy=
# export HTTP_PROXY=
echo "Test-4"
kubectl -v9 get pod
echo "Test-5"
echo $K8S_POD_NAME
timestamp=$(date +%s)
echo $timestamp
kubectl annotate pods $K8S_POD_NAME JOBSTART=$timestamp
echo "Test-5"

View File

@@ -23,5 +23,7 @@
<key>ACTIONS_RUNNER_SVC</key>
<string>1</string>
</dict>
<key>ProcessType</key>
<string>Interactive</string>
</dict>
</plist>

View File

@@ -1,23 +0,0 @@
#!/bin/bash
set -euo pipefail
EVENT=$1
TIMESTAMP=$2
echo $EVENT
echo $TIMESTAMP
function fatal() {
echo "error: $1" >&2
exit 1
}
[ -n "${K8S_POD_NAME:-""}" ] || fatal "K8S_POD_NAME variable must be set"
echo $K8S_POD_NAME
kubectl get pod
kubectl annotate pods $K8S_POD_NAME $EVENT=$TIMESTAMP
echo "DONE"

View File

@@ -33,9 +33,6 @@ namespace GitHub.Runner.Common
[DataMember(EmitDefaultValue = false)]
public string PoolName { get; set; }
[DataMember(EmitDefaultValue = false)]
public bool Ephemeral { get; set; }
[DataMember(EmitDefaultValue = false)]
public string ServerUrl { get; set; }

View File

@@ -90,7 +90,7 @@ namespace GitHub.Runner.Common
public static readonly string Labels = "labels";
public static readonly string MonitorSocketAddress = "monitorsocketaddress";
public static readonly string Name = "name";
public static readonly string Pool = "pool";
public static readonly string RunnerGroup = "runnergroup";
public static readonly string StartupType = "startuptype";
public static readonly string Url = "url";
public static readonly string UserName = "username";
@@ -99,11 +99,9 @@ namespace GitHub.Runner.Common
// Secret args. Must be added to the "Secrets" getter as well.
public static readonly string Token = "token";
public static readonly string PAT = "pat";
public static readonly string WindowsLogonPassword = "windowslogonpassword";
public static string[] Secrets => new[]
{
PAT,
Token,
WindowsLogonPassword,
};
@@ -122,9 +120,9 @@ namespace GitHub.Runner.Common
public static class Flags
{
public static readonly string Commit = "commit";
public static readonly string Ephemeral = "ephemeral";
public static readonly string Help = "help";
public static readonly string Replace = "replace";
public static readonly string Once = "once";
public static readonly string RunAsService = "runasservice";
public static readonly string Unattended = "unattended";
public static readonly string Version = "version";

View File

@@ -28,10 +28,10 @@ namespace GitHub.Runner.Listener
private readonly string[] validFlags =
{
Constants.Runner.CommandLine.Flags.Commit,
Constants.Runner.CommandLine.Flags.Ephemeral,
Constants.Runner.CommandLine.Flags.Help,
Constants.Runner.CommandLine.Flags.Replace,
Constants.Runner.CommandLine.Flags.RunAsService,
Constants.Runner.CommandLine.Flags.Once,
Constants.Runner.CommandLine.Flags.Unattended,
Constants.Runner.CommandLine.Flags.Version
};
@@ -42,8 +42,7 @@ namespace GitHub.Runner.Listener
Constants.Runner.CommandLine.Args.Labels,
Constants.Runner.CommandLine.Args.MonitorSocketAddress,
Constants.Runner.CommandLine.Args.Name,
Constants.Runner.CommandLine.Args.PAT,
Constants.Runner.CommandLine.Args.Pool,
Constants.Runner.CommandLine.Args.RunnerGroup,
Constants.Runner.CommandLine.Args.StartupType,
Constants.Runner.CommandLine.Args.Token,
Constants.Runner.CommandLine.Args.Url,
@@ -64,7 +63,8 @@ namespace GitHub.Runner.Listener
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);
// Constructor.
public CommandSettings(IHostContext context, string[] args)
@@ -169,6 +169,15 @@ namespace GitHub.Runner.Listener
validator: Validators.NonEmptyValidator);
}
public string GetRunnerGroupName(string defaultPoolName = null)
{
return GetArgOrPrompt(
name: Constants.Runner.CommandLine.Args.RunnerGroup,
description: "Enter the name of the runner group to add this runner to:",
defaultValue: defaultPoolName ?? "default",
validator: Validators.NonEmptyValidator);
}
public string GetToken()
{
return GetArgOrPrompt(
@@ -178,11 +187,6 @@ namespace GitHub.Runner.Listener
validator: Validators.NonEmptyValidator);
}
public string GetGitHubPersonalAccessToken()
{
return GetArg(name: Constants.Runner.CommandLine.Args.PAT);
}
public string GetRunnerRegisterToken()
{
return GetArgOrPrompt(

View File

@@ -7,13 +7,11 @@ using GitHub.Services.OAuth;
using GitHub.Services.WebApi;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace GitHub.Runner.Listener.Configuration
@@ -109,21 +107,8 @@ namespace GitHub.Runner.Listener.Configuration
else
{
runnerSettings.GitHubUrl = inputUrl;
var githubPAT = command.GetGitHubPersonalAccessToken();
var registerToken = string.Empty;
if (!string.IsNullOrEmpty(githubPAT))
{
Trace.Info("Retriving runner register token using GitHub PAT.");
var jitToken = await GetJITRunnerTokenAsync(inputUrl, githubPAT, "registration");
Trace.Info($"Retrived runner register token is good to {jitToken.ExpiresAt}.");
HostContext.SecretMasker.AddValue(jitToken.Token);
registerToken = jitToken.Token;
}
if (string.IsNullOrEmpty(registerToken))
{
registerToken = command.GetRunnerRegisterToken();
}
GitHubAuthResult authResult = await GetTenantCredential(inputUrl, registerToken, Constants.RunnerEvent.Register);
var githubToken = command.GetRunnerRegisterToken();
GitHubAuthResult authResult = await GetTenantCredential(inputUrl, githubToken, Constants.RunnerEvent.Register);
runnerSettings.ServerUrl = authResult.TenantUrl;
creds = authResult.ToVssCredentials();
Trace.Info("cred retrieved via GitHub auth");
@@ -174,17 +159,34 @@ namespace GitHub.Runner.Listener.Configuration
_term.WriteSection("Runner Registration");
//Get all the agent pools, and select the first private pool
// If we have more than one runner group available, allow the user to specify which one to be added into
string poolName = null;
TaskAgentPool agentPool = null;
List<TaskAgentPool> agentPools = await _runnerServer.GetAgentPoolsAsync();
TaskAgentPool agentPool = agentPools?.Where(x => x.IsHosted == false).FirstOrDefault();
TaskAgentPool defaultPool = agentPools?.Where(x => x.IsInternal).FirstOrDefault();
if (agentPool == null)
if (agentPools?.Where(x => !x.IsHosted).Count() > 1)
{
throw new TaskAgentPoolNotFoundException($"Could not find any private pool. Contact support.");
poolName = command.GetRunnerGroupName(defaultPool?.Name);
_term.WriteLine();
agentPool = agentPools.Where(x => string.Equals(poolName, x.Name, StringComparison.OrdinalIgnoreCase) && !x.IsHosted).FirstOrDefault();
}
else
{
Trace.Info("Found a private pool with id {1} and name {2}", agentPool.Id, agentPool.Name);
agentPool = defaultPool;
}
if (agentPool == null && poolName == null)
{
throw new TaskAgentPoolNotFoundException($"Could not find any self-hosted runner groups. Contact support.");
}
else if (agentPool == null && poolName != null)
{
throw new TaskAgentPoolNotFoundException($"Could not find any self-hosted runner group named \"{poolName}\".");
}
else
{
Trace.Info("Found a self-hosted runner group with id {1} and name {2}", agentPool.Id, agentPool.Name);
runnerSettings.PoolId = agentPool.Id;
runnerSettings.PoolName = agentPool.Name;
}
@@ -192,7 +194,6 @@ namespace GitHub.Runner.Listener.Configuration
TaskAgent agent;
while (true)
{
runnerSettings.Ephemeral = command.Ephemeral;
runnerSettings.AgentName = command.GetRunnerName();
_term.WriteLine();
@@ -209,7 +210,7 @@ namespace GitHub.Runner.Listener.Configuration
if (command.GetReplace())
{
// Update existing agent with new PublicKey, agent version.
agent = UpdateExistingAgent(agent, publicKey, userLabels, runnerSettings.Ephemeral);
agent = UpdateExistingAgent(agent, publicKey, userLabels);
try
{
@@ -232,7 +233,7 @@ namespace GitHub.Runner.Listener.Configuration
else
{
// Create a new agent.
agent = CreateNewAgent(runnerSettings.AgentName, publicKey, userLabels, runnerSettings.Ephemeral);
agent = CreateNewAgent(runnerSettings.AgentName, publicKey, userLabels);
try
{
@@ -372,22 +373,8 @@ namespace GitHub.Runner.Listener.Configuration
}
else
{
var githubPAT = command.GetGitHubPersonalAccessToken();
var deletionToken = string.Empty;
if (!string.IsNullOrEmpty(githubPAT))
{
Trace.Info("Retriving runner deletion token using GitHub PAT.");
var jitToken = await GetJITRunnerTokenAsync(settings.GitHubUrl, githubPAT, "remove");
Trace.Info($"Retrived runner deletion token is good to {jitToken.ExpiresAt}.");
HostContext.SecretMasker.AddValue(jitToken.Token);
deletionToken = jitToken.Token;
}
if (string.IsNullOrEmpty(deletionToken))
{
deletionToken = command.GetRunnerDeletionToken();
}
GitHubAuthResult authResult = await GetTenantCredential(settings.GitHubUrl, deletionToken, Constants.RunnerEvent.Remove);
var githubToken = command.GetRunnerDeletionToken();
GitHubAuthResult authResult = await GetTenantCredential(settings.GitHubUrl, githubToken, Constants.RunnerEvent.Remove);
creds = authResult.ToVssCredentials();
Trace.Info("cred retrieved via GitHub auth");
}
@@ -470,7 +457,7 @@ namespace GitHub.Runner.Listener.Configuration
}
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral)
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey, ISet<string> userLabels)
{
ArgUtil.NotNull(agent, nameof(agent));
agent.Authorization = new TaskAgentAuthorization
@@ -481,8 +468,6 @@ namespace GitHub.Runner.Listener.Configuration
// update should replace the existing labels
agent.Version = BuildConstants.RunnerPackage.Version;
agent.OSDescription = RuntimeInformation.OSDescription;
agent.Ephemeral = ephemeral;
agent.MaxParallelism = 1;
agent.Labels.Clear();
@@ -498,7 +483,7 @@ namespace GitHub.Runner.Listener.Configuration
return agent;
}
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral)
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels)
{
TaskAgent agent = new TaskAgent(agentName)
{
@@ -509,7 +494,6 @@ namespace GitHub.Runner.Listener.Configuration
MaxParallelism = 1,
Version = BuildConstants.RunnerPackage.Version,
OSDescription = RuntimeInformation.OSDescription,
Ephemeral = ephemeral,
};
agent.Labels.Add(new AgentLabel("self-hosted", LabelType.System));
@@ -531,72 +515,6 @@ namespace GitHub.Runner.Listener.Configuration
string.Equals(gitHubUrl.Host, "github.localhost", StringComparison.OrdinalIgnoreCase);
}
private async Task<GitHubRunnerRegisterToken> GetJITRunnerTokenAsync(string githubUrl, string githubToken, string tokenType)
{
var githubApiUrl = "";
var gitHubUrlBuilder = new UriBuilder(githubUrl);
var path = gitHubUrlBuilder.Path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
if (path.Length == 1)
{
if (IsHostedServer(gitHubUrlBuilder))
{
githubApiUrl = $"{gitHubUrlBuilder.Scheme}://api.{gitHubUrlBuilder.Host}/orgs/{path[0]}/actions/runners/{tokenType}-token";
}
else
{
githubApiUrl = $"{gitHubUrlBuilder.Scheme}://{gitHubUrlBuilder.Host}/api/v3/orgs/{path[0]}/actions/runners/{tokenType}-token";
}
}
if (path.Length == 2)
{
var repoScope = "repos/";
if (string.Equals(path[0], "enterprises", StringComparison.OrdinalIgnoreCase))
{
repoScope = "";
}
if (IsHostedServer(gitHubUrlBuilder))
{
githubApiUrl = $"{gitHubUrlBuilder.Scheme}://api.{gitHubUrlBuilder.Host}/{repoScope}{path[0]}/{path[1]}/actions/runners/{tokenType}-token";
}
else
{
githubApiUrl = $"{gitHubUrlBuilder.Scheme}://{gitHubUrlBuilder.Host}/api/v3/{repoScope}{path[0]}/{path[1]}/actions/runners/{tokenType}-token";
}
}
else
{
throw new ArgumentException($"'{githubUrl}' should point to an org or repository.");
}
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
using (var httpClient = new HttpClient(httpClientHandler))
{
var base64EncodingToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"github:{githubToken}"));
HostContext.SecretMasker.AddValue(base64EncodingToken);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", base64EncodingToken);
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.github.v3+json");
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(string.Empty));
if (response.IsSuccessStatusCode)
{
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
var jsonResponse = await response.Content.ReadAsStringAsync();
return StringUtil.ConvertFromJson<GitHubRunnerRegisterToken>(jsonResponse);
}
else
{
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
var errorResponse = await response.Content.ReadAsStringAsync();
_term.WriteError(errorResponse);
response.EnsureSuccessStatusCode();
return null;
}
}
}
private async Task<GitHubAuthResult> GetTenantCredential(string githubUrl, string githubToken, string runnerEvent)
{
var githubApiUrl = "";

View File

@@ -71,16 +71,6 @@ namespace GitHub.Runner.Listener.Configuration
}
}
[DataContract]
public sealed class GitHubRunnerRegisterToken
{
[DataMember(Name = "token")]
public string Token { get; set; }
[DataMember(Name = "expires_at")]
public string ExpiresAt { get; set; }
}
[DataContract]
public sealed class GitHubAuthResult
{

View File

@@ -477,53 +477,6 @@ namespace GitHub.Runner.Listener
var systemConnection = message.Resources.Endpoints.SingleOrDefault(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase));
var accessToken = systemConnection?.Authorization?.Parameters["AccessToken"];
notification.JobStarted(message.JobId, accessToken, systemConnection.Url);
var jobStartNotification = Environment.GetEnvironmentVariable("_INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION");
if (!string.IsNullOrEmpty(jobStartNotification))
{
term.WriteLine($"{DateTime.UtcNow:u}: Publish JobStart to {jobStartNotification}");
using (var jobStartInvoker = HostContext.CreateService<IProcessInvoker>())
{
jobStartInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
{
if (!string.IsNullOrEmpty(stdout.Data))
{
Trace.Info($"JobStartNotification: {stdout.Data}");
}
};
jobStartInvoker.ErrorDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stderr)
{
if (!string.IsNullOrEmpty(stderr.Data))
{
if (!string.IsNullOrEmpty(stderr.Data))
{
Trace.Error($"JobStartNotification: {stderr.Data}");
}
}
};
try
{
await jobStartInvoker.ExecuteAsync(
workingDirectory: HostContext.GetDirectory(WellKnownDirectory.Root),
fileName: WhichUtil.Which("bash"),
arguments: $"-c \"{jobStartNotification} JOBSTART {DateTime.UtcNow.ToString("O")}\"",
environment: null,
requireExitCodeZero: true,
outputEncoding: null,
killProcessOnCancel: true,
redirectStandardIn: null,
inheritConsoleHandler: false,
keepStandardInOpen: false,
highPriorityProcess: true,
cancellationToken: new CancellationTokenSource(10000).Token);
}
catch (Exception ex)
{
Trace.Error($"Fail to publish JobStart notification: {ex}");
}
}
}
HostContext.WritePerfCounter($"SentJobToWorker_{requestId.ToString()}");
@@ -660,53 +613,6 @@ namespace GitHub.Runner.Listener
{
// This should be the last thing to run so we don't notify external parties until actually finished
await notification.JobCompleted(message.JobId);
var jobCompleteNotification = Environment.GetEnvironmentVariable("_INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION");
if (!string.IsNullOrEmpty(jobCompleteNotification))
{
term.WriteLine($"{DateTime.UtcNow:u}: Publish JobComplete to {jobCompleteNotification}");
using (var jobCompleteInvoker = HostContext.CreateService<IProcessInvoker>())
{
jobCompleteInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
{
if (!string.IsNullOrEmpty(stdout.Data))
{
Trace.Info($"jobCompleteNotification: {stdout.Data}");
}
};
jobCompleteInvoker.ErrorDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stderr)
{
if (!string.IsNullOrEmpty(stderr.Data))
{
if (!string.IsNullOrEmpty(stderr.Data))
{
Trace.Error($"jobCompleteNotification: {stderr.Data}");
}
}
};
try
{
await jobCompleteInvoker.ExecuteAsync(
workingDirectory: HostContext.GetDirectory(WellKnownDirectory.Root),
fileName: WhichUtil.Which("bash"),
arguments: $"-c \"{jobCompleteNotification} JOBCOMPLETE {DateTime.UtcNow.ToString("O")}\"",
environment: null,
requireExitCodeZero: true,
outputEncoding: null,
killProcessOnCancel: true,
redirectStandardIn: null,
inheritConsoleHandler: false,
keepStandardInOpen: false,
highPriorityProcess: true,
cancellationToken: new CancellationTokenSource(10000).Token);
}
catch (Exception ex)
{
Trace.Error($"Fail to publish JobComplete notification: {ex}");
}
}
}
}
}
}
@@ -739,56 +645,7 @@ namespace GitHub.Runner.Listener
// fire first renew succeed event.
firstJobRequestRenewed.TrySetResult(0);
}
else
{
var jobRunningNotification = Environment.GetEnvironmentVariable("_INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION");
if (!string.IsNullOrEmpty(jobRunningNotification))
{
HostContext.GetService<ITerminal>().WriteLine($"{DateTime.UtcNow:u}: Publish JobRunning to {jobRunningNotification}");
using (var jobRunningInvoker = HostContext.CreateService<IProcessInvoker>())
{
jobRunningInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
{
if (!string.IsNullOrEmpty(stdout.Data))
{
Trace.Info($"JobRunningNotification: {stdout.Data}");
}
};
jobRunningInvoker.ErrorDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stderr)
{
if (!string.IsNullOrEmpty(stderr.Data))
{
if (!string.IsNullOrEmpty(stderr.Data))
{
Trace.Error($"JobRunningNotification: {stderr.Data}");
}
}
};
try
{
await jobRunningInvoker.ExecuteAsync(
workingDirectory: HostContext.GetDirectory(WellKnownDirectory.Root),
fileName: WhichUtil.Which("bash"),
arguments: $"-c \"{jobRunningNotification} JOBRUNNING {DateTime.UtcNow.ToString("O")}\"",
environment: null,
requireExitCodeZero: true,
outputEncoding: null,
killProcessOnCancel: true,
redirectStandardIn: null,
inheritConsoleHandler: false,
keepStandardInOpen: false,
highPriorityProcess: true,
cancellationToken: new CancellationTokenSource(10000).Token);
}
catch (Exception ex)
{
Trace.Error($"Fail to publish JobRunning notification: {ex}");
}
}
}
}
if (encounteringError > 0)
{
encounteringError = 0;

View File

@@ -193,7 +193,7 @@ namespace GitHub.Runner.Listener
HostContext.StartupType = startType;
// Run the runner interactively or as service
return await RunAsync(settings, settings.Ephemeral);
return await RunAsync(settings, command.RunOnce);
}
else
{
@@ -462,19 +462,20 @@ Options:
--commit Prints the runner commit
Config Options:
--unattended Disable interactive prompts for missing arguments. Defaults will be used for missing options
--url string Repository to add the runner to. Required if unattended
--token string Registration token. Required if unattended
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
--replace Replace any existing runner with the same name (default false)");
--unattended Disable interactive prompts for missing arguments. Defaults will be used for missing options
--url string Repository to add the runner to. Required if unattended
--token string Registration token. Required if unattended
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
--runnergroup string Name of the runner group to add this runner to (defaults to the default runner group)
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
--replace Replace any existing runner with the same name (default false)");
#if OS_WINDOWS
_term.WriteLine($@" --runasservice Run the runner as a service");
_term.WriteLine($@" --windowslogonaccount string Account to run the service as. Requires runasservice");
_term.WriteLine($@" --windowslogonpassword string Password for the service account. Requires runasservice");
#endif
_term.WriteLine($@"
_term.WriteLine($@"
Examples:
Configure a runner non-interactively:
.{separator}config.{ext} --unattended --url <url> --token <token>

View File

@@ -59,53 +59,6 @@ namespace GitHub.Runner.Listener
Trace.Info($"An update is available.");
var runnerUpdateNotification = Environment.GetEnvironmentVariable("_INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION");
if (!string.IsNullOrEmpty(runnerUpdateNotification))
{
HostContext.GetService<ITerminal>().WriteLine($"{DateTime.UtcNow:u}: Publish RunnerUpdate to {runnerUpdateNotification}");
using (var runnerUpdateInvoker = HostContext.CreateService<IProcessInvoker>())
{
runnerUpdateInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
{
if (!string.IsNullOrEmpty(stdout.Data))
{
Trace.Info($"RunnerUpdateNotification: {stdout.Data}");
}
};
runnerUpdateInvoker.ErrorDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stderr)
{
if (!string.IsNullOrEmpty(stderr.Data))
{
if (!string.IsNullOrEmpty(stderr.Data))
{
Trace.Error($"RunnerUpdateNotification: {stderr.Data}");
}
}
};
try
{
await runnerUpdateInvoker.ExecuteAsync(
workingDirectory: HostContext.GetDirectory(WellKnownDirectory.Root),
fileName: WhichUtil.Which("bash"),
arguments: $"-c \"{runnerUpdateNotification} RUNNERUPDATE {DateTime.UtcNow.ToString("O")}\"",
environment: null,
requireExitCodeZero: true,
outputEncoding: null,
killProcessOnCancel: true,
redirectStandardIn: null,
inheritConsoleHandler: false,
keepStandardInOpen: false,
highPriorityProcess: true,
cancellationToken: new CancellationTokenSource(10000).Token);
}
catch (Exception ex)
{
Trace.Error($"Fail to publish RunnerUpdate notification: {ex}");
}
}
}
// Print console line that warn user not shutdown runner.
await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");

View File

@@ -395,7 +395,7 @@ namespace GitHub.Runner.Worker
Trace.Info($"Action cleanup plugin: {plugin.PluginTypeName}.");
}
}
else if (definition.Data.Execution.ExecutionType == ActionExecutionType.Composite && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
else if (definition.Data.Execution.ExecutionType == ActionExecutionType.Composite)
{
var compositeAction = definition.Data.Execution as CompositeActionExecutionData;
Trace.Info($"Load {compositeAction.Steps?.Count ?? 0} action steps.");
@@ -1048,7 +1048,7 @@ namespace GitHub.Runner.Worker
Trace.Info($"Action plugin: {(actionDefinitionData.Execution as PluginActionExecutionData).Plugin}, no more preparation.");
return null;
}
else if (actionDefinitionData.Execution.ExecutionType == ActionExecutionType.Composite && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
else if (actionDefinitionData.Execution.ExecutionType == ActionExecutionType.Composite)
{
Trace.Info($"Action composite: {(actionDefinitionData.Execution as CompositeActionExecutionData).Steps}, no more preparation.");
return null;

View File

@@ -30,6 +30,8 @@ namespace GitHub.Runner.Worker
Dictionary<string, string> EvaluateContainerEnvironment(IExecutionContext executionContext, MappingToken token, IDictionary<string, PipelineContextData> extraExpressionValues);
string EvaluateDefaultInput(IExecutionContext executionContext, string inputName, TemplateToken token);
// string EvaluateDefaultInputInsideComposite(IExecutionContext executionContext, string inputName, TemplateToken token);
}
public sealed class ActionManifestManager : RunnerService, IActionManifestManager
@@ -105,12 +107,7 @@ namespace GitHub.Runner.Worker
break;
case "outputs":
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
{
actionOutputs = actionPair.Value.AssertMapping("outputs");
break;
}
Trace.Info($"Ignore action property outputs. Outputs for a whole action is not supported yet.");
actionOutputs = actionPair.Value.AssertMapping("outputs");
break;
case "description":
@@ -287,6 +284,9 @@ namespace GitHub.Runner.Worker
if (token != null)
{
var templateContext = CreateTemplateContext(executionContext);
Trace.Info($"Template context GitHub: {StringUtil.ConvertToJson(templateContext.ExpressionValues["github"])}");
Trace.Info($"Template context keys: {StringUtil.ConvertToJson(templateContext.ExpressionValues.Keys)}");
try
{
var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "input-default-context", token, 0, null, omitHeader: true);
@@ -309,6 +309,83 @@ namespace GitHub.Runner.Worker
return result;
}
// public string EvaluateDefaultInputInsideComposite(
// IExecutionContext executionContext,
// string inputName,
// TemplateToken token)
// {
// string result = "";
// if (token != null)
// {
// // Add GitHub Expression Values
// var githubContext = executionContext.ExpressionValues["github"];
// Trace.Info($"GitHub Context EvaluateDefaultInputInsideComposite: {StringUtil.ConvertToJson(githubContext)}");
// var temp = new Dictionary<string, PipelineContextData>();
// temp["github"] = githubContext;
// // Trace.Info($"Token: {StringUtil.ConvertToJson(token)}");
// var templateContext = CreateTemplateContext(executionContext, temp);
// try
// {
// var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "uses-input", token, 0, null, omitHeader: true);
// Trace.Info($"Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
// templateContext.Errors.Check();
// // Can't evaluate the default github.respository, etc.
// // TODO: restrict to only be used for composite "uses" steps
// // Find better way to isolate only
// // We could create a whitelist for just checkout?
// // (ex: "repo", "token", etc.)
// // if (evaluateResult is BasicExpressionToken)
// // {
// // // var evaluateResult2 = TemplateEvaluator.Evaluate(templateContext, "step-with", token, 0, null, omitHeader: true);
// // // templateContext.Errors.Check();
// // // Trace.Info($"Test2 Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult2)}");
// // // var result2 = evaluateResult2.AssertString($"default value for input '{inputName}'").Value;
// // // TODO 6/28 => Try just getting it from the getgithubcontext lmao.
// // // Trace.Info($"Basic expr token: {evaluateResult}");
// // var stringVersion = evaluateResult.AssertString($"default value for input '{inputName}'").Value;
// // // no we have to use the template evaluator since it's a
// // // var githubTokenSplit =
// // // // Evaluate it
// // // var evaluateResult = executionContext.GetGitHubContext("");
// // return result2;
// // }
// // Trace.Info($"Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
// // String
// result = evaluateResult.AssertString($"default value for input '{inputName}'").Value;
// }
// catch (Exception ex) when (!(ex is TemplateValidationException))
// {
// Trace.Error(ex);
// templateContext.Errors.Add(ex);
// }
// templateContext.Errors.Check();
// }
// return result;
// }
private TemplateContext CreateTemplateContext(
IExecutionContext executionContext,
IDictionary<string, PipelineContextData> extraExpressionValues = null)
@@ -423,14 +500,10 @@ namespace GitHub.Runner.Worker
preIfToken = run.Value.AssertString("pre-if");
break;
case "steps":
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
{
var stepsToken = run.Value.AssertSequence("steps");
steps = PipelineTemplateConverter.ConvertToSteps(templateContext, stepsToken);
templateContext.Errors.Check();
break;
}
throw new Exception("You aren't supposed to be using Composite Actions yet!");
var stepsToken = run.Value.AssertSequence("steps");
steps = PipelineTemplateConverter.ConvertToSteps(templateContext, stepsToken);
templateContext.Errors.Check();
break;
default:
Trace.Info($"Ignore run property {runsKey}.");
break;
@@ -478,7 +551,7 @@ namespace GitHub.Runner.Worker
};
}
}
else if (string.Equals(usingToken.Value, "composite", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
else if (string.Equals(usingToken.Value, "composite", StringComparison.OrdinalIgnoreCase))
{
if (steps == null)
{

View File

@@ -169,6 +169,25 @@ namespace GitHub.Runner.Worker
validInputs.Add("entryPoint");
validInputs.Add("args");
}
Trace.Info($"Repo: {ExecutionContext.GetGitHubContext("repository")}");
// Since we don't pass the GitHub Context attributes to the composite action,
// We need to explitly set the default values of certain things we need like the
// default repository
// if (ExecutionContext.GetGitHubContext("repository") == null)
// {
// ExecutionContext.SetGitHubContext("repository", definition.Directory);
// }
// var githubContext = ExecutionContext.ExpressionValues["github"] as GitHubContext;
// foreach (var pair in githubContext)
// {
// ExecutionContext.SetGitHubContext(pair.Key, pair.Value as StringContextData);
// }
// Merge the default inputs from the definition
if (definition.Data?.Inputs != null)
{
@@ -179,7 +198,17 @@ namespace GitHub.Runner.Worker
validInputs.Add(key);
if (!inputs.ContainsKey(key))
{
Trace.Info($"Definition Input Key: {key}");
// if (ExecutionContext.InsideComposite)
// {
// inputs[key] = manifestManager.EvaluateDefaultInputInsideComposite(ExecutionContext, key, input.Value);
// }
// else
// {
// inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
// }
inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
Trace.Info($"Definition Input Value: {inputs[key]}");
}
}
}

View File

@@ -140,11 +140,6 @@ namespace GitHub.Runner.Worker
executionContext.JobContext.Container["network"] = new StringContextData(containerNetwork);
executionContext.Output("##[endgroup]");
if (Environment.GetEnvironmentVariable("K8S_POD_NAME") != null)
{
IOUtil.CopyDirectory(HostContext.GetDirectory(WellKnownDirectory.Externals), Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), "__externals_copy"), CancellationToken.None);
}
foreach (var container in containers)
{
container.ContainerNetwork = containerNetwork;
@@ -241,14 +236,7 @@ namespace GitHub.Runner.Worker
#if OS_WINDOWS
container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals))));
#else
if (Environment.GetEnvironmentVariable("K8S_POD_NAME") != null)
{
container.MountVolumes.Add(new MountVolume(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), "__externals_copy"), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), true));
}
else
{
container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), true));
}
container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), true));
#endif
container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Temp), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Temp))));
container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Actions), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Actions))));

View File

@@ -53,19 +53,21 @@ namespace GitHub.Runner.Worker
JobContext JobContext { get; }
// Only job level ExecutionContext has JobSteps
List<IStep> JobSteps { get; }
Queue<IStep> JobSteps { get; }
// Only job level ExecutionContext has PostJobSteps
Stack<IStep> PostJobSteps { get; }
bool EchoOnActionCommand { get; set; }
bool InsideComposite { get; }
ExecutionContext Root { get; }
// Initialize
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
void CancelToken();
IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, CancellationTokenSource cancellationTokenSource = null);
IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, bool insideComposite = false, CancellationTokenSource cancellationTokenSource = null);
// logging
long Write(string tag, string message);
@@ -142,7 +144,7 @@ namespace GitHub.Runner.Worker
public GlobalContext Global { get; private set; }
// Only job level ExecutionContext has JobSteps
public List<IStep> JobSteps { get; private set; }
public Queue<IStep> JobSteps { get; private set; }
// Only job level ExecutionContext has PostJobSteps
public Stack<IStep> PostJobSteps { get; private set; }
@@ -152,6 +154,8 @@ namespace GitHub.Runner.Worker
public bool EchoOnActionCommand { get; set; }
public bool InsideComposite { get; private set; }
public TaskResult? Result
{
get
@@ -256,7 +260,7 @@ namespace GitHub.Runner.Worker
DictionaryContextData inputsData,
Dictionary<string, string> envData)
{
step.ExecutionContext = Root.CreateChild(_record.Id, step.DisplayName, _record.Id.ToString("N"), scopeName, step.Action.ContextName, logger: _logger, cancellationTokenSource: CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token));
step.ExecutionContext = Root.CreateChild(_record.Id, step.DisplayName, _record.Id.ToString("N"), scopeName, step.Action.ContextName, logger: _logger, insideComposite: true, cancellationTokenSource: CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token));
step.ExecutionContext.ExpressionValues["inputs"] = inputsData;
step.ExecutionContext.ExpressionValues["steps"] = Global.StepsContext.GetScope(step.ExecutionContext.GetFullyQualifiedContextName());
@@ -275,7 +279,7 @@ namespace GitHub.Runner.Worker
return step;
}
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, CancellationTokenSource cancellationTokenSource = null)
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, bool insideComposite = false, CancellationTokenSource cancellationTokenSource = null)
{
Trace.Entering();
@@ -322,6 +326,8 @@ namespace GitHub.Runner.Worker
child._logger.Setup(_mainTimelineId, recordId);
}
child.InsideComposite = insideComposite;
return child;
}
@@ -657,7 +663,7 @@ namespace GitHub.Runner.Worker
Global.PrependPath = new List<string>();
// JobSteps for job ExecutionContext
JobSteps = new List<IStep>();
JobSteps = new Queue<IStep>();
// PostJobSteps for job ExecutionContext
PostJobSteps = new Stack<IStep>();

View File

@@ -9,6 +9,7 @@ namespace GitHub.Runner.Worker
private readonly HashSet<string> _contextEnvWhitelist = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"action",
"action_path",
"actor",
"api_url",
"base_ref",

View File

@@ -5,11 +5,14 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GitHub.DistributedTask.Expressions2;
using GitHub.DistributedTask.ObjectTemplating.Tokens;
using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Common;
using GitHub.Runner.Sdk;
using GitHub.Runner.Worker.Expressions;
using Pipelines = GitHub.DistributedTask.Pipelines;
@@ -35,6 +38,8 @@ namespace GitHub.Runner.Worker.Handlers
var githubContext = ExecutionContext.ExpressionValues["github"] as GitHubContext;
ArgUtil.NotNull(githubContext, nameof(githubContext));
// Trace.Info($"Github Context: {StringUtil.ConvertToJson(githubContext)}");
// Resolve action steps
var actionSteps = Data.Steps;
@@ -45,6 +50,8 @@ namespace GitHub.Runner.Worker.Handlers
inputsData[i.Key] = new StringContextData(i.Value);
}
Trace.Info($"Composite Actions Inputs {StringUtil.ConvertToJson(inputsData)}");
// Initialize Composite Steps List of Steps
var compositeSteps = new List<IStep>();
@@ -56,6 +63,18 @@ namespace GitHub.Runner.Worker.Handlers
childScopeName = $"__{Guid.NewGuid()}";
}
// Copy the github context so that we don't modify the original pointer
// We can't use PipelineContextData.Clone() since that creates a null pointer exception for copying a GitHubContext
var compositeGitHubContext = new GitHubContext();
foreach (var pair in githubContext)
{
compositeGitHubContext[pair.Key] = pair.Value;
}
// Download all data
var actionManager = HostContext.GetService<IActionManager>();
await actionManager.PrepareActionsAsync(ExecutionContext, actionSteps);
foreach (Pipelines.ActionStep actionStep in actionSteps)
{
var actionRunner = HostContext.CreateService<IActionRunner>();
@@ -64,6 +83,12 @@ namespace GitHub.Runner.Worker.Handlers
actionRunner.Condition = actionStep.Condition;
var step = ExecutionContext.CreateCompositeStep(childScopeName, actionRunner, inputsData, Environment);
// Set GITHUB_ACTION_PATH
step.ExecutionContext.ExpressionValues["github"] = compositeGitHubContext;
step.ExecutionContext.SetGitHubContext("action_path", ActionDirectory);
step.ExecutionContext.ExpressionFunctions.Add(new FunctionInfo<HashFilesFunction>(PipelineTemplateConstants.HashFiles, 1, byte.MaxValue));
compositeSteps.Add(step);
}
@@ -137,6 +162,7 @@ namespace GitHub.Runner.Worker.Handlers
{
ArgUtil.NotNull(compositeSteps, nameof(compositeSteps));
// The parent StepsRunner of the whole Composite Action Step handles the cancellation stuff already.
foreach (IStep step in compositeSteps)
{
@@ -176,9 +202,6 @@ namespace GitHub.Runner.Worker.Handlers
var actionStep = step as IActionRunner;
// Set GITHUB_ACTION
step.ExecutionContext.SetGitHubContext("action", step.ExecutionContext.GetFullyQualifiedContextName());
try
{
// Evaluate and merge action's env block to env context
@@ -215,12 +238,6 @@ namespace GitHub.Runner.Worker.Handlers
private async Task RunStepAsync(IStep step)
{
// Try to evaluate the display name
if (step is IActionRunner actionRunner && actionRunner.Stage == ActionRunStage.Main)
{
actionRunner.TryEvaluateDisplayName(step.ExecutionContext.ExpressionValues, step.ExecutionContext);
}
// Start the step.
Trace.Info("Starting the step.");
step.ExecutionContext.Debug($"Starting: {step.DisplayName}");

View File

@@ -82,10 +82,6 @@ namespace GitHub.Runner.Worker.Handlers
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext);
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");
if (System.Environment.GetEnvironmentVariable("K8S_POD_NAME") != null)
{
file = Path.Combine(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), "__externals_copy"), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");
}
// Format the arguments passed to node.
// 1) Wrap the script file path in double quotes.

View File

@@ -23,6 +23,19 @@ namespace GitHub.Runner.Worker.Handlers
public override void PrintActionDetails(ActionRunStage stage)
{
// We don't want to display the internal workings if composite (similar/equivalent information can be found in debug)
void writeDetails(string message)
{
if (ExecutionContext.InsideComposite)
{
ExecutionContext.Debug(message);
}
else
{
ExecutionContext.Output(message);
}
}
if (stage == ActionRunStage.Post)
{
throw new NotSupportedException("Script action should not have 'Post' job action.");
@@ -39,7 +52,7 @@ namespace GitHub.Runner.Worker.Handlers
firstLine = firstLine.Substring(0, firstNewLine);
}
ExecutionContext.Output($"##[group]Run {firstLine}");
writeDetails(ExecutionContext.InsideComposite ? $"Run {firstLine}" : $"##[group]Run {firstLine}");
}
else
{
@@ -50,7 +63,7 @@ namespace GitHub.Runner.Worker.Handlers
foreach (var line in multiLines)
{
// Bright Cyan color
ExecutionContext.Output($"\x1b[36;1m{line}\x1b[0m");
writeDetails($"\x1b[36;1m{line}\x1b[0m");
}
string argFormat;
@@ -109,23 +122,23 @@ namespace GitHub.Runner.Worker.Handlers
if (!string.IsNullOrEmpty(shellCommandPath))
{
ExecutionContext.Output($"shell: {shellCommandPath} {argFormat}");
writeDetails($"shell: {shellCommandPath} {argFormat}");
}
else
{
ExecutionContext.Output($"shell: {shellCommand} {argFormat}");
writeDetails($"shell: {shellCommand} {argFormat}");
}
if (this.Environment?.Count > 0)
{
ExecutionContext.Output("env:");
writeDetails("env:");
foreach (var env in this.Environment)
{
ExecutionContext.Output($" {env.Key}: {env.Value}");
writeDetails($" {env.Key}: {env.Value}");
}
}
ExecutionContext.Output("##[endgroup]");
writeDetails(ExecutionContext.InsideComposite ? "" : "##[endgroup]");
}
public async Task RunAsync(ActionRunStage stage)
@@ -151,8 +164,6 @@ namespace GitHub.Runner.Worker.Handlers
string workingDirectory = null;
if (!Inputs.TryGetValue("workingDirectory", out workingDirectory))
{
// TODO: figure out how defaults interact with template later
// for now, we won't check job.defaults if we are inside a template.
if (string.IsNullOrEmpty(ExecutionContext.ScopeName) && ExecutionContext.Global.JobDefaults.TryGetValue("run", out var runDefaults))
{
if (runDefaults.TryGetValue("working-directory", out workingDirectory))
@@ -167,8 +178,6 @@ namespace GitHub.Runner.Worker.Handlers
string shell = null;
if (!Inputs.TryGetValue("shell", out shell) || string.IsNullOrEmpty(shell))
{
// TODO: figure out how defaults interact with template later
// for now, we won't check job.defaults if we are inside a template.
if (string.IsNullOrEmpty(ExecutionContext.ScopeName) && ExecutionContext.Global.JobDefaults.TryGetValue("run", out var runDefaults))
{
if (runDefaults.TryGetValue("shell", out shell))

View File

@@ -152,7 +152,7 @@ namespace GitHub.Runner.Worker
{
foreach (var step in jobSteps)
{
jobContext.JobSteps.Add(step);
jobContext.JobSteps.Enqueue(step);
}
await stepsRunner.RunAsync(jobContext);

View File

@@ -59,14 +59,13 @@ namespace GitHub.Runner.Worker
checkPostJobActions = true;
while (jobContext.PostJobSteps.TryPop(out var postStep))
{
jobContext.JobSteps.Add(postStep);
jobContext.JobSteps.Enqueue(postStep);
}
continue;
}
var step = jobContext.JobSteps[0];
jobContext.JobSteps.RemoveAt(0);
var step = jobContext.JobSteps.Dequeue();
Trace.Info($"Processing step: DisplayName='{step.DisplayName}'");
ArgUtil.NotNull(step.ExecutionContext, nameof(step.ExecutionContext));

View File

@@ -108,19 +108,46 @@
}
},
"composite-steps": {
"context": [
"github",
"strategy",
"matrix",
"steps",
"inputs",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"sequence": {
"item-type": "any"
"item-type": "composite-step-types"
}
},
"composite-step-types": {
"one-of": [
"composite-step",
"uses-step"
]
},
"composite-step": {
"mapping": {
"properties": {
"name": "string-steps-context",
"id": "non-empty-string",
"run": {
"type": "string-steps-context",
"required": true
},
"env": "step-env",
"working-directory": "string-steps-context",
"shell": {
"type": "non-empty-string",
"required": true
}
}
}
},
"uses-step": {
"mapping": {
"properties": {
"name": "string-steps-context",
"id": "non-empty-string",
"uses": {
"type": "non-empty-string",
"required": true
},
"with": "step-with",
"env": "step-env"
}
}
},
"container-runs-context": {
@@ -157,6 +184,68 @@
"string": {
"require-non-empty": true
}
},
"string-steps-context": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"string": {}
},
"step-env": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"mapping": {
"loose-key-type": "non-empty-string",
"loose-value-type": "string"
}
},
"step-with": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"mapping": {
"loose-key-type": "non-empty-string",
"loose-value-type": "string"
}
},
"uses-input": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"string": {}
}
}
}

View File

@@ -29,6 +29,7 @@ namespace GitHub.DistributedTask.WebApi
this.PoolType = referenceToBeCloned.PoolType;
this.Size = referenceToBeCloned.Size;
this.IsLegacy = referenceToBeCloned.IsLegacy;
this.IsInternal = referenceToBeCloned.IsInternal;
}
public TaskAgentPoolReference Clone()
@@ -67,6 +68,16 @@ namespace GitHub.DistributedTask.WebApi
set;
}
/// <summary>
/// Gets or sets a value indicating whether or not this pool is internal and can't be modified by users
/// </summary>
[DataMember]
public bool IsInternal
{
get;
set;
}
/// <summary>
/// Gets or sets the type of the pool
/// </summary>

View File

@@ -24,7 +24,6 @@ namespace GitHub.DistributedTask.WebApi
this.OSDescription = referenceToBeCloned.OSDescription;
this.ProvisioningState = referenceToBeCloned.ProvisioningState;
this.AccessPoint = referenceToBeCloned.AccessPoint;
this.Ephemeral = referenceToBeCloned.Ephemeral;
if (referenceToBeCloned.m_links != null)
{
@@ -82,16 +81,6 @@ namespace GitHub.DistributedTask.WebApi
set;
}
/// <summary>
/// Signifies that this Agent can only run one job and will be removed by the server after that one job finish.
/// </summary>
[DataMember]
public bool? Ephemeral
{
get;
set;
}
/// <summary>
/// Whether or not the agent is online.
/// </summary>

View File

@@ -1,58 +1,58 @@
// using Xunit;
// using System.IO;
// using System.Net.Http;
// using System.Threading.Tasks;
using Xunit;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
// namespace GitHub.Runner.Common.Tests
// {
// public sealed class DotnetsdkDownloadScriptL0
// {
// [Fact]
// [Trait("Level", "L0")]
// [Trait("Category", "Runner")]
// public async Task EnsureDotnetsdkBashDownloadScriptUpToDate()
// {
// string shDownloadUrl = "https://dot.net/v1/dotnet-install.sh";
namespace GitHub.Runner.Common.Tests
{
public sealed class DotnetsdkDownloadScriptL0
{
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Runner")]
public async Task EnsureDotnetsdkBashDownloadScriptUpToDate()
{
string shDownloadUrl = "https://dot.net/v1/dotnet-install.sh";
// using (HttpClient downloadClient = new HttpClient())
// {
// var response = await downloadClient.GetAsync("https://www.bing.com");
// if (!response.IsSuccessStatusCode)
// {
// return;
// }
using (HttpClient downloadClient = new HttpClient())
{
var response = await downloadClient.GetAsync("https://www.bing.com");
if (!response.IsSuccessStatusCode)
{
return;
}
// string shScript = await downloadClient.GetStringAsync(shDownloadUrl);
string shScript = await downloadClient.GetStringAsync(shDownloadUrl);
// string existingShScript = File.ReadAllText(Path.Combine(TestUtil.GetSrcPath(), "Misc/dotnet-install.sh"));
string existingShScript = File.ReadAllText(Path.Combine(TestUtil.GetSrcPath(), "Misc/dotnet-install.sh"));
// bool shScriptMatched = string.Equals(shScript.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"), existingShScript.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"));
// Assert.True(shScriptMatched, "Fix the test by updating Src/Misc/dotnet-install.sh with content from https://dot.net/v1/dotnet-install.sh");
// }
// }
bool shScriptMatched = string.Equals(shScript.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"), existingShScript.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"));
Assert.True(shScriptMatched, "Fix the test by updating Src/Misc/dotnet-install.sh with content from https://dot.net/v1/dotnet-install.sh");
}
}
// [Fact]
// [Trait("Level", "L0")]
// [Trait("Category", "Runner")]
// public async Task EnsureDotnetsdkPowershellDownloadScriptUpToDate()
// {
// string ps1DownloadUrl = "https://dot.net/v1/dotnet-install.ps1";
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Runner")]
public async Task EnsureDotnetsdkPowershellDownloadScriptUpToDate()
{
string ps1DownloadUrl = "https://dot.net/v1/dotnet-install.ps1";
// using (HttpClient downloadClient = new HttpClient())
// {
// var response = await downloadClient.GetAsync("https://www.bing.com");
// if (!response.IsSuccessStatusCode)
// {
// return;
// }
using (HttpClient downloadClient = new HttpClient())
{
var response = await downloadClient.GetAsync("https://www.bing.com");
if (!response.IsSuccessStatusCode)
{
return;
}
// string ps1Script = await downloadClient.GetStringAsync(ps1DownloadUrl);
string ps1Script = await downloadClient.GetStringAsync(ps1DownloadUrl);
// string existingPs1Script = File.ReadAllText(Path.Combine(TestUtil.GetSrcPath(), "Misc/dotnet-install.ps1"));
string existingPs1Script = File.ReadAllText(Path.Combine(TestUtil.GetSrcPath(), "Misc/dotnet-install.ps1"));
// bool ps1ScriptMatched = string.Equals(ps1Script.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"), existingPs1Script.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"));
// Assert.True(ps1ScriptMatched, "Fix the test by updating Src/Misc/dotnet-install.ps1 with content from https://dot.net/v1/dotnet-install.ps1");
// }
// }
// }
// }
bool ps1ScriptMatched = string.Equals(ps1Script.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"), existingPs1Script.TrimEnd('\n', '\r', '\0').Replace("\r\n", "\n").Replace("\r", "\n"));
Assert.True(ps1ScriptMatched, "Fix the test by updating Src/Misc/dotnet-install.ps1 with content from https://dot.net/v1/dotnet-install.ps1");
}
}
}
}

View File

@@ -39,10 +39,12 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
private string _expectedToken = "expectedToken";
private string _expectedServerUrl = "https://codedev.ms";
private string _expectedAgentName = "expectedAgentName";
private string _expectedPoolName = "poolName";
private string _defaultRunnerGroupName = "defaultRunnerGroup";
private string _secondRunnerGroupName = "secondRunnerGroup";
private string _expectedAuthType = "pat";
private string _expectedWorkFolder = "_work";
private int _expectedPoolId = 1;
private int _defaultRunnerGroupId = 1;
private int _secondRunnerGroupId = 2;
private RSACryptoServiceProvider rsa = null;
private RunnerSettings _configMgrAgentSettings = new RunnerSettings();
@@ -97,7 +99,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
_serviceControlManager.Setup(x => x.GenerateScripts(It.IsAny<RunnerSettings>()));
#endif
var expectedPools = new List<TaskAgentPool>() { new TaskAgentPool(_expectedPoolName) { Id = _expectedPoolId } };
var expectedPools = new List<TaskAgentPool>() { new TaskAgentPool(_defaultRunnerGroupName) { Id = _defaultRunnerGroupId, IsInternal = true }, new TaskAgentPool(_secondRunnerGroupName) { Id = _secondRunnerGroupId } };
_runnerServer.Setup(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.IsAny<TaskAgentPoolType>())).Returns(Task.FromResult(expectedPools));
var expectedAgents = new List<TaskAgent>();
@@ -155,7 +157,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
"configure",
"--url", _expectedServerUrl,
"--name", _expectedAgentName,
"--pool", _expectedPoolName,
"--runnergroup", _secondRunnerGroupName,
"--work", _expectedWorkFolder,
"--auth", _expectedAuthType,
"--token", _expectedToken,
@@ -175,7 +177,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
Assert.NotNull(s);
Assert.True(s.ServerUrl.Equals(_expectedServerUrl));
Assert.True(s.AgentName.Equals(_expectedAgentName));
Assert.True(s.PoolId.Equals(_expectedPoolId));
Assert.True(s.PoolId.Equals(_secondRunnerGroupId));
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
// validate GetAgentPoolsAsync gets called twice with automation pool type

View File

@@ -243,8 +243,7 @@ namespace GitHub.Runner.Common.Tests.Listener
runner.Initialize(hc);
var settings = new RunnerSettings
{
PoolId = 43242,
Ephemeral = true
PoolId = 43242
};
var message = new TaskAgentMessage()
@@ -295,7 +294,7 @@ namespace GitHub.Runner.Common.Tests.Listener
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
//Act
var command = new CommandSettings(hc, new string[] { "run" });
var command = new CommandSettings(hc, new string[] { "run", "--once" });
Task<int> runnerTask = runner.ExecuteCommand(command);
//Assert
@@ -333,8 +332,7 @@ namespace GitHub.Runner.Common.Tests.Listener
runner.Initialize(hc);
var settings = new RunnerSettings
{
PoolId = 43242,
Ephemeral = true
PoolId = 43242
};
var message1 = new TaskAgentMessage()
@@ -392,7 +390,7 @@ namespace GitHub.Runner.Common.Tests.Listener
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
//Act
var command = new CommandSettings(hc, new string[] { "run" });
var command = new CommandSettings(hc, new string[] { "run", "--once" });
Task<int> runnerTask = runner.ExecuteCommand(command);
//Assert
@@ -433,8 +431,7 @@ namespace GitHub.Runner.Common.Tests.Listener
var settings = new RunnerSettings
{
PoolId = 43242,
AgentId = 5678,
Ephemeral = true
AgentId = 5678
};
var message1 = new TaskAgentMessage()
@@ -478,7 +475,7 @@ namespace GitHub.Runner.Common.Tests.Listener
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
//Act
var command = new CommandSettings(hc, new string[] { "run" });
var command = new CommandSettings(hc, new string[] { "run", "--once" });
Task<int> runnerTask = runner.ExecuteCommand(command);
//Assert

View File

@@ -82,7 +82,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -117,7 +117,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -156,7 +156,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -210,7 +210,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -289,7 +289,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Steps.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -332,7 +332,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Step.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Step.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -363,7 +363,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -393,7 +393,7 @@ namespace GitHub.Runner.Common.Tests.Worker
{
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(variableSet.Select(x => x.Object).ToList()));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(variableSet.Select(x => x.Object).ToList()));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -419,7 +419,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(new[] { step1.Object }));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -457,7 +457,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(new[] { step1.Object, step2.Object }));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object, step2.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -495,7 +495,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(new[] { step1.Object, step2.Object }));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object, step2.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -526,7 +526,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(new[] { step1.Object, step2.Object, step3.Object }));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object, step2.Object, step3.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
@@ -562,7 +562,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new List<IStep>(new[] { step1.Object, step2.Object, step3.Object }));
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object, step2.Object, step3.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);

View File

@@ -1 +1 @@
2.299.0
2.274.0

View File

@@ -1,6 +0,0 @@
apt-get update
apt-get install -y apt-transport-https gnupg2
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubectl