coder/code-server

7 workflows · maturity 83% · 6 patterns · GitHub ↗

Security 35.12/100

Practices

✓ Matrix✓ Permissions✓ Security scan○ AI review✓ Cache✓ Concurrency○ Reusable workflows

Detected patterns

Security dimensions

permissions
14.3
security scan
20.8
supply chain
0
secret handling
0
harden runner
0

Tools: aquasecurity/trivy-action, github/codeql-action/analyze, github/codeql-action/autobuild, github/codeql-action/init, github/codeql-action/upload-sarif

Workflows (7)

build .github/workflows/build.yaml
Triggers
push, pull_request
Runs on
ubuntu-latest, ubuntu-22.04, ubuntu-22.04, ubuntu-22.04, ubuntu-22.04, ubuntu-latest, ubuntu-22.04, ubuntu-22.04, ubuntu-22.04, ubuntu-22.04
Jobs
changes, prettier, doctoc, lint-helm, lint-ts, lint-actions, test-unit, build, test-e2e, test-e2e-proxy
Actions
dorny/paths-filter, azure/setup-helm, codecov/codecov-action, awalsh128/cache-apt-pkgs-action
Commands
  • echo "${{ toJSON(steps.filter )}}"
  • SKIP_SUBMODULE_DEPS=1 npm ci
  • npx prettier --check .
  • SKIP_SUBMODULE_DEPS=1 npm ci
  • npm run doctoc
  • helm plugin install https://github.com/instrumenta/helm-kubeval
  • helm kubeval ci/helm-chart
  • SKIP_SUBMODULE_DEPS=1 npm ci
View raw YAML
name: Build

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      ci: ${{ steps.filter.outputs.ci }}
      code: ${{ steps.filter.outputs.code }}
      deps: ${{ steps.filter.outputs.deps }}
      docs: ${{ steps.filter.outputs.docs }}
      helm: ${{ steps.filter.outputs.helm }}
    steps:
      - uses: actions/checkout@v6
      - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
        id: filter
        with:
          filters: |
            ci:
              - ".github/**"
              - "ci/**"
            docs:
              - "docs/**"
              - "README.md"
              - "CHANGELOG.md"
            helm:
              - "ci/helm-chart/**"
            code:
              - "src/**"
              - "test/**"
            deps:
              - "lib/**"
              - "patches/**"
              - "package-lock.json"
              - "test/package-lock.json"
      - id: debug
        run: |
          echo "${{ toJSON(steps.filter )}}"

  prettier:
    name: Run prettier check
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - run: npx prettier --check .

  doctoc:
    name: Doctoc markdown files
    runs-on: ubuntu-22.04
    needs: changes
    if: needs.changes.outputs.docs == 'true'
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - run: npm run doctoc

  lint-helm:
    name: Lint Helm chart
    runs-on: ubuntu-22.04
    needs: changes
    if: needs.changes.outputs.helm == 'true'
    steps:
      - uses: actions/checkout@v6
      - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - run: helm plugin install https://github.com/instrumenta/helm-kubeval
      - run: helm kubeval ci/helm-chart

  lint-ts:
    name: Lint TypeScript files
    runs-on: ubuntu-22.04
    needs: changes
    if: needs.changes.outputs.code == 'true'
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - run: npm run lint:ts

  lint-actions:
    name: Lint GitHub Actions
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.ci == 'true'
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6
      - name: Check workflow files
        run: |
          bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.9
          ./actionlint -color -shellcheck= -ignore "softprops/action-gh-release"
        shell: bash

  test-unit:
    name: Run unit tests
    runs-on: ubuntu-22.04
    needs: changes
    if: needs.changes.outputs.code == 'true'
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - run: npm run test:unit
      - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5
        if: success()
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  build:
    name: linux-x64
    runs-on: ubuntu-22.04
    env:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
      DISABLE_V8_COMPILE_CACHE: 1
      VERSION: 0.0.0
      VSCODE_TARGET: linux-x64
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - run: sudo apt update && sudo apt install -y libkrb5-dev
      - uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # latest
        with:
          packages: quilt
          version: 1.0

      - uses: actions/checkout@v6
        with:
          submodules: true
      - run: quilt push -a
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - run: npm run build
      # Get Code's git hash.  When this changes it means the content is
      # different and we need to rebuild.
      - name: Get latest lib/vscode rev
        id: vscode-rev
        run: echo "rev=$(git rev-parse HEAD:./lib/vscode)" >> $GITHUB_OUTPUT
      # We need to rebuild when we have a new version of Code, when any of the
      # patches changed, or when the code-server version changes (since it gets
      # embedded into the code).  Use VSCODE_CACHE_VERSION to force a rebuild.
      - name: Fetch prebuilt linux-x64 Code package from cache
        id: cache-vscode
        uses: actions/cache@v4
        with:
          path: lib/vscode-reh-web-linux-x64
          key: vscode-linux-x64-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
      - name: Build vscode
        if: steps.cache-vscode.outputs.cache-hit != 'true'
        run: |
          pushd lib/vscode
          npm ci
          popd
          npm run build:vscode
      # Push up an artifact containing the linux-x64 release.
      - run: KEEP_MODULES=1 npm run release
      - run: tar -czf package.tar.gz release
      - uses: actions/upload-artifact@v7
        with:
          name: linux-x64-package
          path: ./package.tar.gz

  test-e2e:
    name: Run e2e tests
    runs-on: ubuntu-22.04
    needs: [changes, build]
    if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true'

    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - name: Install Playwright OS dependencies
        run: |
          ./test/node_modules/.bin/playwright install-deps
          ./test/node_modules/.bin/playwright install

      - uses: actions/download-artifact@v8
        with:
          name: linux-x64-package
      - run: tar -xzf package.tar.gz

      - run: CODE_SERVER_TEST_ENTRY=./release npm run test:e2e
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: failed-test-videos
          path: ./test/test-results

  test-e2e-proxy:
    name: Run e2e tests behind proxy
    runs-on: ubuntu-22.04
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    needs: [changes, build]
    if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true'

    steps:
      - name: Cache Caddy
        uses: actions/cache@v4
        id: caddy-cache
        with:
          path: |
            ~/.cache/caddy
          key: cache-caddy-2.5.2
      - name: Install Caddy
        if: steps.caddy-cache.outputs.cache-hit != 'true'
        run: |
          gh release download v2.5.2 --repo caddyserver/caddy --pattern "caddy_2.5.2_linux_amd64.tar.gz"
          mkdir -p ~/.cache/caddy
          tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy

      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: SKIP_SUBMODULE_DEPS=1 npm ci
      - name: Install Playwright OS dependencies
        run: |
          ./test/node_modules/.bin/playwright install-deps
          ./test/node_modules/.bin/playwright install

      - uses: actions/download-artifact@v8
        with:
          name: linux-x64-package
      - run: tar -xzf package.tar.gz

      - run: ~/.cache/caddy/caddy start --config ./ci/Caddyfile
      - run: CODE_SERVER_TEST_ENTRY=./release npm run test:e2e:proxy
      - run: ~/.cache/caddy/caddy stop --config ./ci/Caddyfile
        if: always()
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: failed-test-videos-proxy
          path: ./test/test-results
installer perms .github/workflows/installer.yaml
Triggers
push, pull_request
Runs on
ubuntu-latest, ubuntu-latest, macos-latest
Jobs
ubuntu, alpine, macos
Commands
  • ./install.sh
  • code-server --help
  • apk add curl
  • adduser coder --disabled-password
  • su coder -c "./install.sh --method standalone --prefix /tmp/does/not/yet/exist"
  • test -f /tmp/does/not/yet/exist/bin/code-server
  • ./install.sh
  • code-server --help
View raw YAML
name: Installer integration

on:
  push:
    branches:
      - main
    paths:
      - "install.sh"
      - ".github/workflows/installer.yaml"
  pull_request:
    branches:
      - main
    paths:
      - "install.sh"
      - ".github/workflows/installer.yaml"

# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
  contents: read

jobs:
  ubuntu:
    name: Test installer on Ubuntu
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6

      - name: Install code-server
        run: ./install.sh

      - name: Test code-server was installed globally
        run: code-server --help

  alpine:
    name: Test installer on Alpine
    runs-on: ubuntu-latest
    container: "alpine:3.17"
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6

      - name: Install curl
        run: apk add curl

      - name: Add user
        run: adduser coder --disabled-password

      # Standalone should work without root.
      - name: Test standalone to a non-existent prefix
        run: su coder -c "./install.sh --method standalone --prefix /tmp/does/not/yet/exist"

      # We do not actually have Alpine standalone builds so running code-server
      # will not work.
      - name: Test code-server was installed to prefix
        run: test -f /tmp/does/not/yet/exist/bin/code-server

  macos:
    name: Test installer on macOS
    runs-on: macos-latest

    steps:
      - name: Checkout repo
        uses: actions/checkout@v6

      - name: Install code-server
        run: ./install.sh

      - name: Test code-server was installed globally
        run: code-server --help
publish .github/workflows/publish.yaml
Triggers
workflow_dispatch, release
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
npm, aur, docker
Actions
robinraju/release-downloader, heyhusen/archlinux-package-action, docker/setup-qemu-action, docker/setup-buildx-action, docker/login-action, docker/login-action, robinraju/release-downloader, robinraju/release-downloader
Commands
  • echo "VERSION=${TAG#v}" >> $GITHUB_ENV
  • tar -xzf release-npm-package/package.tar.gz
  • echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc pushd release npm publish --tag latest --access public
  • echo "VERSION=${TAG#v}" >> $GITHUB_ENV
  • git remote add upstream https://github.com/coder/code-server-aur.git git fetch upstream git merge upstream/master
  • git config --global user.name cdrci git config --global user.email opensource@coder.com
  • git checkout -b update-version-${{ env.VERSION }} git add . git commit -m "chore: updating version to ${{ env.VERSION }}" git push -u origin $(git branch --show) gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ env.VERSION }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
  • echo "VERSION=${TAG#v}" >> $GITHUB_ENV
View raw YAML
name: Publish code-server

on:
  # Shows the manual trigger in GitHub UI
  # helpful as a back-up in case the GitHub Actions Workflow fails
  workflow_dispatch:
    inputs:
      version:
        type: string
        required: true

  release:
    types: [released]

# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  npm:
    runs-on: ubuntu-latest
    env:
      TAG: ${{ inputs.version || github.ref_name }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
      NPM_ENVIRONMENT: "production"

    steps:
      - name: Set version to tag without leading v
        run: |
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version

      - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12
        with:
          repository: "coder/code-server"
          tag: ${{ inputs.version || github.ref_name }}
          fileName: "package.tar.gz"
          out-file-path: "release-npm-package"

      - run: tar -xzf release-npm-package/package.tar.gz
      - run: |
          echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
          pushd release
          npm publish --tag latest --access public

  aur:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    env:
      GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
      TAG: ${{ inputs.version || github.ref_name }}

    steps:
      - name: Set version to tag without leading v
        run: |
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - name: Checkout code-server-aur repo
        uses: actions/checkout@v6
        with:
          repository: "cdrci/code-server-aur"
          token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
          ref: "master"

      - name: Merge in master
        run: |
          git remote add upstream https://github.com/coder/code-server-aur.git
          git fetch upstream
          git merge upstream/master

      - name: Configure git
        run: |
          git config --global user.name cdrci
          git config --global user.email opensource@coder.com

      - name: Validate package
        uses: heyhusen/archlinux-package-action@c9f94059ccbebe8710d31d582f33ef4e84fe575c # v3.0.0
        with:
          pkgver: ${{ env.VERSION }}
          updpkgsums: true
          srcinfo: true

      - name: Open PR
        run: |
          git checkout -b update-version-${{ env.VERSION }}
          git add .
          git commit -m "chore: updating version to ${{ env.VERSION }}"
          git push -u origin $(git branch --show)
          gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ env.VERSION }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR

  docker:
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ github.token }}
      TAG: ${{ inputs.version || github.ref_name }}

    steps:
      - name: Set version to tag without leading v
        run: |
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - uses: actions/checkout@v6
      - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
      - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

      - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12
        with:
          repository: "coder/code-server"
          tag: v${{ env.VERSION }}
          fileName: "*.deb"
          out-file-path: "release-packages"
      - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12
        with:
          repository: "coder/code-server"
          tag: v${{ env.VERSION }}
          fileName: "*.rpm"
          out-file-path: "release-packages"

      - run: npm run publish:docker
release matrix perms .github/workflows/release.yaml
Triggers
workflow_dispatch
Runs on
ubuntu-latest, ${{ matrix.os }}
Jobs
package-linux, package-macos
Matrix
include, include.apt_arch, include.npm_arch, include.os, include.package_arch, include.prefix, include.vscode_target→ aarch64-linux-gnu, amd64, arm-linux-gnueabihf, arm64, armhf, armv7l, darwin-arm64, darwin-x64, linux-arm64, linux-armhf, linux-x64, macos-15-intel, macos-latest, x64, x86_64-linux-gnu
Actions
softprops/action-gh-release, softprops/action-gh-release, softprops/action-gh-release
Commands
  • sed -i 's/deb\.debian\.org/archive.debian.org/g' /etc/apt/sources.list dpkg --add-architecture $APT_ARCH apt update && apt install -y --no-install-recommends \ crossbuild-essential-$APT_ARCH \ libx11-dev:$APT_ARCH \ libx11-xcb-dev:$APT_ARCH \ libxkbfile-dev:$APT_ARCH \ libsecret-1-dev:$APT_ARCH \ libkrb5-dev:$APT_ARCH \ ca-certificates \ curl wget rsync gettext-base quilt git
  • mkdir -p ~/.local/bin curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm echo "$HOME/.local/bin" >> $GITHUB_PATH
  • echo "VERSION=${TAG#v}" >> $GITHUB_ENV
  • quilt push -a
  • npm ci
  • npm run build
  • npm run build:vscode
  • npm run release
View raw YAML
name: Draft release

on:
  workflow_dispatch:
    inputs:
      version:
        type: string
        required: true

permissions:
  contents: write # For creating releases.
  discussions: write #  For creating a discussion.

# Cancel in-progress runs for pull requests when developers push
# additional changes
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  package-linux:
    name: ${{ matrix.vscode_target }}
    runs-on: ubuntu-latest
    container: "python:3.8-slim-buster"
    strategy:
      matrix:
        include:
          - prefix: x86_64-linux-gnu
            npm_arch: x64
            apt_arch: amd64
            package_arch: amd64
            vscode_target: linux-x64
          - prefix: aarch64-linux-gnu
            npm_arch: arm64
            apt_arch: arm64
            package_arch: arm64
            vscode_target: linux-arm64
          - prefix: arm-linux-gnueabihf
            npm_arch: armv7l
            apt_arch: armhf
            package_arch: armv7l
            vscode_target: linux-armhf

    env:
      AR: ${{ format('{0}-ar', matrix.prefix) }}
      AS: ${{ format('{0}-as', matrix.prefix) }}
      CC: ${{ format('{0}-gcc', matrix.prefix) }}
      CPP: ${{ format('{0}-cpp', matrix.prefix) }}
      CXX: ${{ format('{0}-g++', matrix.prefix) }}
      FC: ${{ format('{0}-gfortran', matrix.prefix) }}
      LD: ${{ format('{0}-ld', matrix.prefix) }}
      STRIP: ${{ format('{0}-strip', matrix.prefix) }}
      PKG_CONFIG_PATH: ${{ format('/usr/lib/{0}/pkgconfig', matrix.prefix) }}
      # Set cross-compiler package arch.
      APT_ARCH: ${{ matrix.apt_arch }}
      # For downloading the right Node.
      npm_config_arch: ${{ matrix.npm_arch }}
      # Overrides package architecture.
      ARCH: ${{ matrix.package_arch }}
      # Not building from source results in an x86_64 argon2, as if
      # npm_config_arch is being ignored.
      npm_config_build_from_source: true
      # Overrides VS Code gulp build target.
      VSCODE_TARGET: ${{ matrix.vscode_target }}
      TAG: ${{ inputs.version || github.ref_name }}

    steps:
      - name: Install cross-compiler and system dependencies
        run: |
          sed -i 's/deb\.debian\.org/archive.debian.org/g' /etc/apt/sources.list
          dpkg --add-architecture $APT_ARCH
          apt update && apt install -y --no-install-recommends \
            crossbuild-essential-$APT_ARCH \
            libx11-dev:$APT_ARCH \
            libx11-xcb-dev:$APT_ARCH \
            libxkbfile-dev:$APT_ARCH \
            libsecret-1-dev:$APT_ARCH \
            libkrb5-dev:$APT_ARCH \
            ca-certificates \
            curl wget rsync gettext-base quilt git
      - name: Install nfpm
        run: |
          mkdir -p ~/.local/bin
          curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Set version to tag without leading v
        run: |
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - uses: actions/checkout@v6
        with:
          submodules: true
      - run: quilt push -a
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: npm ci
      - run: npm run build
      - run: npm run build:vscode

      # Platform-agnostic NPM package.
      - run: npm run release
        if: ${{ matrix.vscode_target == 'linux-x64' }}
      - run: tar -czf package.tar.gz release
        if: ${{ matrix.vscode_target == 'linux-x64' }}
      - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
        if: ${{ matrix.vscode_target == 'linux-x64' }}
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: package.tar.gz

      # Platform-specific release.
      - run: KEEP_MODULES=1 npm run release
      - name: Replace node with cross-compile equivalent
        run: |
          node_version=$(node --version)
          wget https://nodejs.org/dist/${node_version}/node-${node_version}-linux-${npm_config_arch}.tar.xz
          tar -xf node-${node_version}-linux-${npm_config_arch}.tar.xz node-${node_version}-linux-${npm_config_arch}/bin/node --strip-components=2
          mv ./node ./release/lib/node

      - run: npm run package
      - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./release-packages/*

  package-macos:
    name: ${{ matrix.vscode_target }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: macos-15-intel
            vscode_target: darwin-x64
          - os: macos-latest
            vscode_target: darwin-arm64
    env:
      VSCODE_TARGET: ${{ matrix.vscode_target }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      TAG: ${{ inputs.version || github.ref_name }}

    steps:
      # The version of node-gyp we use depends on distutils but it was removed
      # in Python 3.12.  It seems to be fixed in the latest node-gyp so when we
      # next update Node we can probably remove this.  For now, install
      # setuptools since it contains distutils.
      - run: brew install python-setuptools quilt
      - name: Install nfpm
        run: |
          mkdir -p ~/.local/bin
          curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Set version to tag without leading v
        run: |
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - uses: actions/checkout@v6
        with:
          submodules: true
      - run: quilt push -a
      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json
      - run: npm ci
      - run: npm run build
      - run: npm run build:vscode
      - run: KEEP_MODULES=1 npm run release
      - run: npm run test:native

      - run: npm run package
      - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./release-packages/*
scripts perms .github/workflows/scripts.yaml
Triggers
push, pull_request
Runs on
ubuntu-latest, ubuntu-latest
Jobs
test, lint
Commands
  • apk add bats checkbashisms
  • checkbashisms ./install.sh
  • ./ci/dev/test-scripts.sh
  • sudo apt install shellcheck
  • ./ci/dev/lint-scripts.sh
View raw YAML
name: Script unit tests

on:
  push:
    branches:
      - main
    paths:
      - "**.sh"
      - "**.bats"
  pull_request:
    branches:
      - main
    paths:
      - "**.sh"
      - "**.bats"

permissions:
  actions: none
  checks: none
  contents: read
  deployments: none
  issues: none
  packages: none
  pull-requests: none
  repository-projects: none
  security-events: none
  statuses: none

# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  test:
    name: Run script unit tests
    runs-on: ubuntu-latest
    # This runs on Alpine to make sure we're testing with actual sh.
    container: "alpine:3.17"
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6

      - name: Install test utilities
        run: apk add bats checkbashisms

      - name: Check Bashisms
        run: checkbashisms ./install.sh

      - name: Run script unit tests
        run: ./ci/dev/test-scripts.sh

  lint:
    name: Lint shell files
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6

      - name: Install lint utilities
        run: sudo apt install shellcheck

      - name: Lint shell files
        run: ./ci/dev/lint-scripts.sh
security security .github/workflows/security.yaml
Triggers
push, pull_request, schedule
Runs on
ubuntu-latest, ubuntu-22.04, ubuntu-22.04
Jobs
audit, trivy-scan-repo, codeql-analyze
Actions
aquasecurity/trivy-action, github/codeql-action/upload-sarif, github/codeql-action/init, github/codeql-action/autobuild, github/codeql-action/analyze
Commands
  • npm audit
View raw YAML
name: Security

on:
  push:
    branches: [main]
    paths:
      - "package.json"
  pull_request:
    paths:
      - "package.json"
  schedule:
    # Runs every Monday morning PST
    - cron: "17 15 * * 1"

# Cancel in-progress runs for pull requests when developers push additional
# changes, and serialize builds in branches.
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  audit:
    name: Audit node modules
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: .node-version

      - name: Audit npm for vulnerabilities
        run: npm audit
        if: success()

  trivy-scan-repo:
    name: Scan repo with Trivy
    permissions:
      contents: read # for actions/checkout to fetch code
      security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout repo
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Run Trivy vulnerability scanner in repo mode
        uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478
        with:
          scan-type: "fs"
          scan-ref: "."
          ignore-unfixed: true
          format: "template"
          template: "@/contrib/sarif.tpl"
          output: "trivy-repo-results.sarif"
          severity: "HIGH,CRITICAL"

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: "trivy-repo-results.sarif"

  codeql-analyze:
    permissions:
      actions: read # for github/codeql-action/init to get workflow details
      contents: read # for actions/checkout to fetch code
      security-events: write # for github/codeql-action/autobuild to send a status report
    name: Analyze with CodeQL
    runs-on: ubuntu-22.04

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      # Initializes the CodeQL tools for scanning.
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v4
        with:
          config-file: ./.github/codeql-config.yml
          languages: javascript

      - name: Autobuild
        uses: github/codeql-action/autobuild@v4

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v4
trivy-docker perms security .github/workflows/trivy-docker.yaml
Triggers
pull_request, push, schedule, workflow_dispatch
Runs on
ubuntu-22.04
Jobs
trivy-scan-image
Actions
aquasecurity/trivy-action, github/codeql-action/upload-sarif
View raw YAML
name: Trivy Nightly Docker Scan

on:
  # Run scans if the workflow is modified, in order to test the
  # workflow itself. This results in some spurious notifications,
  # but seems okay for testing.
  pull_request:
    branches:
      - main
    paths:
      - .github/workflows/trivy-docker.yaml

  # Run scans against master whenever changes are merged.
  push:
    branches:
      - main
    paths:
      - .github/workflows/trivy-docker.yaml

  schedule:
    # Run at 10:15 am UTC (3:15am PT/5:15am CT)
    # Run at 0 minutes 0 hours of every day.
    - cron: "15 10 * * *"

  workflow_dispatch:

permissions:
  actions: none
  checks: none
  contents: read
  deployments: none
  issues: none
  packages: none
  pull-requests: none
  repository-projects: none
  security-events: write
  statuses: none

# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}

jobs:
  trivy-scan-image:
    runs-on: ubuntu-22.04

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Run Trivy vulnerability scanner in image mode
        uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478
        with:
          image-ref: "docker.io/codercom/code-server:latest"
          ignore-unfixed: true
          format: "sarif"
          output: "trivy-image-results.sarif"
          severity: "HIGH,CRITICAL"

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: "trivy-image-results.sarif"