Skip to content

chore: switch from yarn to pnpm #8822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'main' into colin/pnpm
  • Loading branch information
coadler committed Aug 1, 2023
commit e1339e799f77a9dbac3f09d968c0b1ca77b78d6c
17 changes: 17 additions & 0 deletions .github/workflows/pr-cleanup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,20 @@ jobs:
- name: "Remove PR namespace"
run: |
kubectl delete namespace "pr${{ steps.pr_number.outputs.PR_NUMBER }}" || echo "namespace not found"

- name: "Remove DNS records"
run: |
set -euxo pipefail
# Get identifier for the record
record_id=$(curl -X GET "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records?name=%2A.pr${{ steps.pr_number.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}" \
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" | jq -r '.result[0].id') || echo "DNS record not found"

echo "::add-mask::$record_id"

# Delete the record
(
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records/$record_id" \
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json"
) || echo "DNS record not found"
128 changes: 83 additions & 45 deletions .github/workflows/pr-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ on:
inputs:
pr_number:
description: "PR number"
type: number
required: true
skip_build:
description: "Skip build job"
required: false
type: boolean
default: false
experiments:
description: "Experiments to enable"
required: false
type: string
default: "*"

env:
REPO: ghcr.io/coder/coder-preview
Expand All @@ -22,8 +29,8 @@ permissions:
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}
cancel-in-progress: false
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: true

jobs:
pr_commented:
Expand Down Expand Up @@ -136,7 +143,7 @@ jobs:
PR_TITLE: ${{ needs.pr_commented.outputs.PR_TITLE }}
PR_URL: ${{ needs.pr_commented.outputs.PR_URL }}
PR_BRANCH: ${{ needs.pr_commented.outputs.PR_BRANCH }}
PR_DEPLOYMENT_ACCESS_URL: "https://pr${{ needs.pr_commented.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
PR_DEPLOYMENT_ACCESS_URL: "pr${{ needs.pr_commented.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
steps:
- name: Check if image exists
run: |
Expand All @@ -145,10 +152,19 @@ jobs:
if [ -z "$foundTag" ]; then
echo "Image not found"
echo "${{ env.CODER_IMAGE_TAG }} not found in ghcr.io/coder/coder-preview"
echo "Please remove --skip-build from the comment or ./scripts/deploy-pr.sh"
echo "Please remove --skip-build from the comment and try again"
exit 1
fi

- name: Add DNS record to Cloudflare
run: |
(
curl -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records" \
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" \
--data '{"type":"CNAME","name":"*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}","content":"${{ env.PR_DEPLOYMENT_ACCESS_URL }}","ttl":1,"proxied":false}'
)

- name: Checkout
uses: actions/checkout@v3
with:
Expand All @@ -168,35 +184,36 @@ jobs:
kubectl delete namespace "pr${{ env.PR_NUMBER }}" || true
kubectl create namespace "pr${{ env.PR_NUMBER }}"

- name: Setup ingress
- name: Check and Create Certificate
run: |
cat <<EOF > ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pr${{ env.PR_NUMBER }}
namespace: pr${{ env.PR_NUMBER }}
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- "${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
- "*.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
# Using kubectl to check if a Certificate resource already exists
# we are doing this to avoid letsenrypt rate limits
if ! kubectl get certificate pr${{ env.PR_NUMBER }}-tls -n pr-deployment-certs > /dev/null 2>&1; then
echo "Certificate doesn't exist. Creating a new one."
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: pr${{ env.PR_NUMBER }}-tls
namespace: pr-deployment-certs
spec:
secretName: pr${{ env.PR_NUMBER }}-tls
rules:
- host: "pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: coder
port:
number: 80
issuerRef:
name: letsencrypt
kind: ClusterIssuer
dnsNames:
- "${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
- "*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
EOF
kubectl apply -f ingress.yaml
else
echo "Certificate exists. Skipping certificate creation."
echo "Copy certificate from pr-deployment-certs to pr${{ env.PR_NUMBER }} namespace"
(
kubectl get secret pr${{ env.PR_NUMBER }}-tls -n pr-deployment-certs -o json |
jq 'del(.metadata.namespace,.metadata.creationTimestamp,.metadata.resourceVersion,.metadata.selfLink,.metadata.uid,.metadata.managedFields)' |
kubectl -n pr${{ env.PR_NUMBER }} apply -f -
)
fi

- name: Set up PostgreSQL database
run: |
Expand All @@ -210,6 +227,17 @@ jobs:
kubectl create secret generic coder-db-url -n pr${{ env.PR_NUMBER }} \
--from-literal=url="postgres://coder:coder@coder-db-postgresql.pr${{ env.PR_NUMBER }}.svc.cluster.local:5432/coder?sslmode=disable"

- name: Get experiments
id: get_experiments
run: |
set -euxo pipefail
if [[ ${{ github.event_name }} == "workflow_dispatch" ]]; then
experiments=${{ github.event.inputs.experiments }}
else
experiments=$(echo "${{ github.event.comment.body }}" | grep -oP '(?<=--experiments )[^ ]+')
fi
echo "experiments=$experiments" >> $GITHUB_OUTPUT

- name: Create values.yaml
run: |
cat <<EOF > pr-deploy-values.yaml
Expand All @@ -220,13 +248,22 @@ jobs:
pullPolicy: Always
service:
type: ClusterIP
ingress:
enable: true
className: traefik
host: ${{ env.PR_DEPLOYMENT_ACCESS_URL }}
wildcardHost: "*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
tls:
enable: true
secretName: pr${{ env.PR_NUMBER }}-tls
wildcardSecretName: pr${{ env.PR_NUMBER }}-tls
env:
- name: "CODER_ACCESS_URL"
value: "https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
value: "https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
- name: "CODER_WILDCARD_ACCESS_URL"
value: "*--pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
value: "*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
- name: "CODER_EXPERIMENTS"
value: "*"
value: "*,${{ steps.get_experiments.outputs.experiments }}"
- name: CODER_PG_CONNECTION_URL
valueFrom:
secretKeyRef:
Expand Down Expand Up @@ -261,7 +298,7 @@ jobs:
set -euxo pipefail

DEST="${HOME}/coder"
URL="${{ env.PR_DEPLOYMENT_ACCESS_URL }}/bin/coder-linux-amd64"
URL="https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}/bin/coder-linux-amd64"

mkdir -p "$(dirname ${DEST})"

Expand All @@ -279,6 +316,7 @@ jobs:
curl -fsSL "$URL" -o "${DEST}"
chmod +x "${DEST}"
"${DEST}" version
mv "${DEST}" /usr/local/bin/coder

- name: Create first user, template and workspace
id: setup_deployment
Expand All @@ -294,16 +332,16 @@ jobs:
echo "::add-mask::$password"
echo "password=$password" >> $GITHUB_OUTPUT

/home/runner/coder login \
--first-user-username pr${{ env.PR_NUMBER }} \
--first-user-email ${{ env.PR_NUMBER }}@coder.com \
coder login \
--first-user-username test \
--first-user-email pr${{ env.PR_NUMBER }}@coder.com \
--first-user-password $password \
--first-user-trial \
--use-token-as-session \
${{ env.PR_DEPLOYMENT_ACCESS_URL }}
https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}

# Create template
/home/runner/coder templates init --id kubernetes && cd ./kubernetes/ && /home/runner/coder templates create -y --variable namespace=pr${{ env.PR_NUMBER }}
coder templates init --id kubernetes && cd ./kubernetes/ && coder templates create -y --variable namespace=pr${{ env.PR_NUMBER }}

# Create workspace
cat <<EOF > workspace.yaml
Expand All @@ -312,8 +350,8 @@ jobs:
home_disk_size: "2"
EOF

/home/runner/coder create --template="kubernetes" pr${{ env.PR_NUMBER }} --rich-parameter-file ./workspace.yaml -y
/home/runner/coder stop pr${{ env.PR_NUMBER }} -y
coder create --template="kubernetes" test --rich-parameter-file ./workspace.yaml -y
coder stop test -y

- name: Send Slack notification
run: |
Expand All @@ -323,9 +361,9 @@ jobs:
"pr_number": "'"${{ env.PR_NUMBER }}"'",
"pr_url": "'"${{ env.PR_URL }}"'",
"pr_title": "'"${{ env.PR_TITLE }}"'",
"pr_access_url": "'"${{ env.PR_DEPLOYMENT_ACCESS_URL }}"'",
"pr_username": "'"pr${{ env.PR_NUMBER }}"'",
"pr_email": "'"${{ env.PR_NUMBER }}@coder.com"'",
"pr_access_url": "'"https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}"'",
"pr_username": "'"test"'",
"pr_email": "'"pr${{ env.PR_NUMBER }}@coder.com"'",
"pr_password": "'"${{ steps.setup_deployment.outputs.password }}"'",
"pr_actor": "'"${{ github.actor }}"'"
}' \
Expand All @@ -351,6 +389,6 @@ jobs:
comment-id: ${{ steps.fc.outputs.comment-id }}
body: |
:heavy_check_mark: Deployed PR ${{ env.PR_NUMBER }} successfully.
:rocket: Access the deployment link [here](${{ env.PR_DEPLOYMENT_ACCESS_URL }}).
:rocket: Access the deployment link [here](https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}).
:warning: This deployment will be deleted when the PR is closed.
reactions: rocket
2 changes: 2 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ jobs:
- name: Comment on PR
if: ${{ !inputs.dry_run }}
run: |
# wait 30 seconds
Start-Sleep -Seconds 30.0
# Find the PR that wingetcreate just made.
$version = "${{ needs.release.outputs.version }}".Trim('v')
$pr_list = gh pr list --repo microsoft/winget-pkgs --search "author:cdrci Coder.Coder version ${version}" --limit 1 --json number | `
Expand Down
6 changes: 6 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ type Client interface {

type Agent interface {
HTTPDebug() http.Handler
// TailnetConn may be nil.
TailnetConn() *tailnet.Conn
io.Closer
}

Expand Down Expand Up @@ -200,6 +202,10 @@ type agent struct {
metrics *agentMetrics
}

func (a *agent) TailnetConn() *tailnet.Conn {
return a.network
}

func (a *agent) init(ctx context.Context) {
sshSrv, err := agentssh.NewServer(ctx, a.logger.Named("ssh-server"), a.prometheusRegistry, a.filesystem, a.sshMaxTimeout, "")
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,15 @@ func TestAgent_UpdatedDERP(t *testing.T) {
})
require.NoError(t, err)

require.Eventually(t, func() bool {
conn := closer.TailnetConn()
if conn == nil {
return false
}
regionIDs := conn.DERPMap().RegionIDs()
return len(regionIDs) == 1 && regionIDs[0] == 2 && conn.Node().PreferredDERP == 2
}, testutil.WaitLong, testutil.IntervalFast)

// Connect from a second client and make sure it uses the new DERP map.
conn2 := newClientConn(newDerpMap)
require.Equal(t, []int{2}, conn2.DERPMap().RegionIDs())
Expand Down
20 changes: 16 additions & 4 deletions coderd/coderdtest/coderdtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,21 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
accessURL = serverURL
}

stunAddr, stunCleanup := stuntest.ServeWithPacketListener(t, nettype.Std{})
stunAddr.IP = net.ParseIP("127.0.0.1")
t.Cleanup(stunCleanup)
// If the STUNAddresses setting is empty or the default, start a STUN
// server. Otherwise, use the value as is.
var (
stunAddresses []string
dvStunAddresses = options.DeploymentValues.DERP.Server.STUNAddresses.Value()
)
if len(dvStunAddresses) == 0 || (len(dvStunAddresses) == 1 && dvStunAddresses[0] == "stun.l.google.com:19302") {
stunAddr, stunCleanup := stuntest.ServeWithPacketListener(t, nettype.Std{})
stunAddr.IP = net.ParseIP("127.0.0.1")
t.Cleanup(stunCleanup)
stunAddresses = []string{stunAddr.String()}
options.DeploymentValues.DERP.Server.STUNAddresses = stunAddresses
} else if dvStunAddresses[0] != "disable" {
stunAddresses = options.DeploymentValues.DERP.Server.STUNAddresses.Value()
}

derpServer := derp.NewServer(key.NewNode(), tailnet.Logger(slogtest.Make(t, nil).Named("derp").Leveled(slog.LevelDebug)))
derpServer.SetMeshKey("test-key")
Expand Down Expand Up @@ -346,7 +358,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
if !options.DeploymentValues.DERP.Server.Enable.Value() {
region = nil
}
derpMap, err := tailnet.NewDERPMap(ctx, region, []string{stunAddr.String()}, "", "", options.DeploymentValues.DERP.Config.BlockDirect.Value())
derpMap, err := tailnet.NewDERPMap(ctx, region, stunAddresses, "", "", options.DeploymentValues.DERP.Config.BlockDirect.Value())
require.NoError(t, err)

return func(h http.Handler) {
Expand Down
11 changes: 3 additions & 8 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -953,14 +953,9 @@ func (q *querier) GetLatestWorkspaceBuilds(ctx context.Context) ([]database.Work
}

func (q *querier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceBuild, error) {
// This is not ideal as not all builds will be returned if the workspace cannot be read.
// This should probably be handled differently? Maybe join workspace builds with workspace
// ownership properties and filter on that.
for _, id := range ids {
_, err := q.GetWorkspaceByID(ctx, id)
if err != nil {
return nil, err
}
// This function is a system function until we implement a join for workspace builds.
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
return nil, err
}

return q.db.GetLatestWorkspaceBuildsByWorkspaceIDs(ctx, ids)
Expand Down
10 changes: 5 additions & 5 deletions coderd/database/dbauthz/dbauthz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,11 +1024,6 @@ func (s *MethodTestSuite) TestWorkspace() {
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID})
check.Args(ws.ID).Asserts(ws, rbac.ActionRead).Returns(b)
}))
s.Run("GetLatestWorkspaceBuildsByWorkspaceIDs", s.Subtest(func(db database.Store, check *expects) {
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID})
check.Args([]uuid.UUID{ws.ID}).Asserts(ws, rbac.ActionRead).Returns(slice.New(b))
}))
s.Run("GetWorkspaceAgentByID", s.Subtest(func(db database.Store, check *expects) {
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
Expand Down Expand Up @@ -1298,6 +1293,11 @@ func (s *MethodTestSuite) TestSystemFunctions() {
LoginType: database.LoginTypeGithub,
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns(l)
}))
s.Run("GetLatestWorkspaceBuildsByWorkspaceIDs", s.Subtest(func(db database.Store, check *expects) {
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID})
check.Args([]uuid.UUID{ws.ID}).Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(slice.New(b))
}))
s.Run("UpsertDefaultProxy", s.Subtest(func(db database.Store, check *expects) {
check.Args(database.UpsertDefaultProxyParams{}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns()
}))
Expand Down
2 changes: 1 addition & 1 deletion coderd/healthcheck/derp.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (r *DERPNodeReport) derpURL() *url.URL {
if r.Node.HostName == "" {
derpURL.Host = r.Node.IPv4
}
if r.Node.DERPPort != 0 {
if r.Node.DERPPort != 0 && !(r.Node.DERPPort == 443 && derpURL.Scheme == "https") && !(r.Node.DERPPort == 80 && derpURL.Scheme == "http") {
derpURL.Host = fmt.Sprintf("%s:%d", derpURL.Host, r.Node.DERPPort)
}

Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.