diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..1eb8c2b --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,23 @@ +# You can pick any Debian/Ubuntu-based image. ๐Ÿ˜Š +FROM mcr.microsoft.com/devcontainers/base:bullseye + +# [Option] Install zsh +ARG INSTALL_ZSH="true" +# [Option] Upgrade OS packages to their latest versions +ARG UPGRADE_PACKAGES="true" + +# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies. +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID +COPY library-scripts/*.sh /tmp/library-scripts/ +RUN bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \ + # Install the Azure CLI + && bash /tmp/library-scripts/azcli-debian.sh \ + # Clean up + && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c868258 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "Azure CLI", + "dockerFile": "Dockerfile", + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.azurecli" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "az --version", + + // Uncomment when using a ptrace-based debugger like C++, Go, and Rust + // "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], + + // Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} diff --git a/.github/workflows/Untitled-1 b/.github/workflows/Untitled-1 new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/google.yml b/.github/workflows/google.yml new file mode 100644 index 0000000..c60c33a --- /dev/null +++ b/.github/workflows/google.yml @@ -0,0 +1,91 @@ +# This workflow will build a docker container, publish it to Google Container Registry, and deploy it to GKE when there is a push to the "master" branch. +# +# To configure this workflow: +# +# 1. Ensure that your repository contains the necessary configuration for your Google Kubernetes Engine cluster, including deployment.yml, kustomization.yml, service.yml, etc. +# +# 2. Create and configure a Workload Identity Provider for GitHub (https://github.com/google-github-actions/auth#setting-up-workload-identity-federation) +# +# 3. Change the values for the GAR_LOCATION, GKE_ZONE, GKE_CLUSTER, IMAGE, REPOSITORY and DEPLOYMENT_NAME environment variables (below). +# +# For more support on how to run the workflow, please visit https://github.com/google-github-actions/setup-gcloud/tree/master/example-workflows/gke-kustomize + +name: Build and Deploy to GKE + +on: + push: + branches: [ "master" ] + +env: + PROJECT_ID: ${{ secrets.GKE_PROJECT }} + GAR_LOCATION: us-central1 # TODO: update region of the Artifact Registry + GKE_CLUSTER: cluster-1 # TODO: update to cluster name + GKE_ZONE: us-central1-c # TODO: update to cluster zone + DEPLOYMENT_NAME: gke-test # TODO: update to deployment name + REPOSITORY: samples # TODO: update to Artifact Registry docker repository + IMAGE: static-site + +jobs: + setup-build-publish-deploy: + name: Setup, Build, Publish, and Deploy + runs-on: ubuntu-latest + environment: production + + permissions: + contents: 'read' + id-token: 'write' + + steps: + - name: Checkout + uses: actions/checkout@v3 + + # Configure Workload Identity Federation and generate an access token. + - id: 'auth' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v0' + with: + token_format: 'access_token' + workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' + service_account: 'my-service-account@my-project.iam.gserviceaccount.com' + + # Alternative option - authentication via credentials json + # - id: 'auth' + # uses: 'google-github-actions/auth@v0' + # with: + # credentials_json: '${{ secrets.GCP_CREDENTIALS }}' + + - name: Docker configuration + run: |- + echo ${{steps.auth.outputs.access_token}} | docker login -u oauth2accesstoken --password-stdin https://$GAR_LOCATION-docker.pkg.dev + # Get the GKE credentials so we can deploy to the cluster + - name: Set up GKE credentials + uses: google-github-actions/get-gke-credentials@v0 + with: + cluster_name: ${{ env.GKE_CLUSTER }} + location: ${{ env.GKE_ZONE }} + + # Build the Docker image + - name: Build + run: |- + docker build \ + --tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE:$GITHUB_SHA" \ + --build-arg GITHUB_SHA="$GITHUB_SHA" \ + --build-arg GITHUB_REF="$GITHUB_REF" \ + . + # Push the Docker image to Google Artifact Registry + - name: Publish + run: |- + docker push "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE:$GITHUB_SHA" + # Set up kustomize + - name: Set up Kustomize + run: |- + curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64 + chmod u+x ./kustomize + # Deploy the Docker image to the GKE cluster + - name: Deploy + run: |- + # replacing the image name in the k8s template + ./kustomize edit set image LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG=$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE:$GITHUB_SHA + ./kustomize build . | kubectl apply -f - + kubectl rollout status deployment/$DEPLOYMENT_NAME + kubectl get services -o wide diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e1c966c --- /dev/null +++ b/.npmignore @@ -0,0 +1,6 @@ +README.md +test-project +definition-manifest.json +.devcontainer/library-scripts/README.md +.vscode +.npmignore diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..078b2d2 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,24 @@ +# Xcode +# Build, test, and archive an Xcode workspace on macOS. +# Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/xcode + +trigger: +- master + +pool: + vmImage: 'macos-latest' + +steps: +- task: Xcode@5 + inputs: + actions: 'build' + scheme: '' + sdk: 'iphoneos' + configuration: 'Release' + xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' +- task: Xcode@5 + inputs: + actions: 'build' + packageApp: false + xcodeVersion: 'default' # Options: 8, 9, 10, 11, 12, default, specifyPath diff --git a/test-project/scripting.azcli b/test-project/scripting.azcli new file mode 100644 index 0000000..1ee1fdb --- /dev/null +++ b/test-project/scripting.azcli @@ -0,0 +1,10 @@ +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +az login +az account list -o table +az account set -s 'Try Out Subscription' + +az functionapp list -o table diff --git a/test-project/test-utils.sh b/test-project/test-utils.sh new file mode 100644 index 0000000..6f17711 --- /dev/null +++ b/test-project/test-utils.sh @@ -0,0 +1,149 @@ +#!/bin/bash +SCRIPT_FOLDER="$(cd "$(dirname $0)" && pwd)" +USERNAME=${1:-vscode} + +if [ -z $HOME ]; then + HOME="/root" +fi + +FAILED=() + +echoStderr() +{ + echo "$@" 1>&2 +} + +check() { + LABEL=$1 + shift + echo -e "\n๐Ÿงช Testing $LABEL" + if "$@"; then + echo "โœ… Passed!" + return 0 + else + echoStderr "โŒ $LABEL check failed." + FAILED+=("$LABEL") + return 1 + fi +} + +checkMultiple() { + PASSED=0 + LABEL="$1" + echo -e "\n๐Ÿงช Testing $LABEL." + shift; MINIMUMPASSED=$1 + shift; EXPRESSION="$1" + while [ "$EXPRESSION" != "" ]; do + if $EXPRESSION; then ((PASSED++)); fi + shift; EXPRESSION=$1 + done + if [ $PASSED -ge $MINIMUMPASSED ]; then + echo "โœ… Passed!" + return 0 + else + echoStderr "โŒ $LABEL check failed." + FAILED+=("$LABEL") + return 1 + fi +} + +checkOSPackages() { + LABEL=$1 + shift + echo -e "\n๐Ÿงช Testing $LABEL" + if dpkg-query --show -f='${Package}: ${Version}\n' "$@"; then + echo "โœ… Passed!" + return 0 + else + echoStderr "โŒ $LABEL check failed." + FAILED+=("$LABEL") + return 1 + fi +} + +checkExtension() { + # Happens asynchronusly, so keep retrying 10 times with an increasing delay + EXTN_ID="$1" + TIMEOUT_SECONDS="${2:-10}" + RETRY_COUNT=0 + echo -e -n "\n๐Ÿงช Looking for extension $1 for maximum of ${TIMEOUT_SECONDS}s" + until [ "${RETRY_COUNT}" -eq "${TIMEOUT_SECONDS}" ] || \ + [ ! -e $HOME/.vscode-server/extensions/${EXTN_ID}* ] || \ + [ ! -e $HOME/.vscode-server-insiders/extensions/${EXTN_ID}* ] || \ + [ ! -e $HOME/.vscode-test-server/extensions/${EXTN_ID}* ] || \ + [ ! -e $HOME/.vscode-remote/extensions/${EXTN_ID}* ] + do + sleep 1s + (( RETRY_COUNT++ )) + echo -n "." + done + + if [ ${RETRY_COUNT} -lt ${TIMEOUT_SECONDS} ]; then + echo -e "\nโœ… Passed!" + return 0 + else + echoStderr -e "\nโŒ Extension $EXTN_ID not found." + FAILED+=("$LABEL") + return 1 + fi +} + +checkCommon() +{ + PACKAGE_LIST="apt-utils \ + git \ + openssh-client \ + less \ + iproute2 \ + procps \ + curl \ + wget \ + unzip \ + nano \ + jq \ + lsb-release \ + ca-certificates \ + apt-transport-https \ + dialog \ + gnupg2 \ + libc6 \ + libgcc1 \ + libgssapi-krb5-2 \ + liblttng-ust0 \ + libstdc++6 \ + zlib1g \ + locales \ + sudo" + + # Actual tests + checkOSPackages "common-os-packages" ${PACKAGE_LIST} + checkMultiple "vscode-server" 1 "[ -d $HOME/.vscode-server/bin ]" "[ -d $HOME/.vscode-server-insiders/bin ]" "[ -d $HOME/.vscode-test-server/bin ]" "[ -d $HOME/.vscode-remote/bin ]" "[ -d $HOME/.vscode-remote/bin ]" + check "non-root-user" id ${USERNAME} + check "locale" [ $(locale -a | grep en_US.utf8) ] + check "sudo" sudo echo "sudo works." + check "zsh" zsh --version + check "oh-my-zsh" [ -d "$HOME/.oh-my-zsh" ] + check "login-shell-path" [ -f "/etc/profile.d/00-restore-env.sh" ] + check "code" which code +} + +reportResults() { + if [ ${#FAILED[@]} -ne 0 ]; then + echoStderr -e "\n๐Ÿ’ฅ Failed tests: ${FAILED[@]}" + exit 1 + else + echo -e "\n๐Ÿ’ฏ All passed!" + exit 0 + fi +} + +fixTestProjectFolderPrivs() { + if [ "${USERNAME}" != "root" ]; then + TEST_PROJECT_FOLDER="${1:-$SCRIPT_FOLDER}" + FOLDER_USER="$(stat -c '%U' "${TEST_PROJECT_FOLDER}")" + if [ "${FOLDER_USER}" != "${USERNAME}" ]; then + echoStderr "WARNING: Test project folder is owned by ${FOLDER_USER}. Updating to ${USERNAME}." + sudo chown -R ${USERNAME} "${TEST_PROJECT_FOLDER}" + fi + fi +} \ No newline at end of file diff --git a/trunk b/trunk new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/trunk @@ -0,0 +1 @@ +