Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
22 changes: 22 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Ensure consistent line endings for shell scripts and text files
* text=auto eol=lf

# Shell scripts must always use LF
*.sh text eol=lf

# Manifests and config
*.yml text eol=lf
*.yaml text eol=lf
*.json text eol=lf
*.xml text eol=lf
*.desktop text eol=lf
*.ini text eol=lf
*.flatpakrepo text eol=lf

# Documentation
*.md text eol=lf

# Binary — do not diff or convert
*.png binary
*.flatpak binary
*.gpg binary
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
70 changes: 70 additions & 0 deletions .github/workflows/flatter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Flatter (signed)

on:
push:
workflow_dispatch:
schedule:
# Rebuild weekly to catch upstream changes
- cron: "0 2 * * 0"

jobs:
flatter:
name: Build Flatpak Packages
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
container:
image: ghcr.io/andyholmes/flatter/freedesktop:25.08
options: --privileged

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Setup GPG
# Skip GPG signing for pull requests (requires secrets from repo owner)
if: ${{ github.triggering_actor == github.repository_owner && github.event_name != 'pull_request' }}
id: gpg
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}

- name: Install Flatpak Dependencies
# The freedesktop Flatter image ships the Platform/Sdk but not the
# Electron BaseApp our manifest needs (`base:`, providing zypak).
# flatpak-builder doesn't auto-install it - unlike a local
# `--install-deps-from=flathub` build, Flatter's own flatpak-builder
# invocation has no such flag, so it must already be present before
# "Build Packages" runs.
run: |
flatpak install --noninteractive flathub \
org.electronjs.Electron2.BaseApp//25.08

- name: Build Packages
uses: andyholmes/flatter@main
with:
files: |
com.visualstudio.code.yaml
gpg-sign: ${{ steps.gpg.outputs.fingerprint }}
upload-pages-artifact: true
upload-pages-includes: |
index.html
README.md

deploy:
name: Deploy
runs-on: ubuntu-latest
needs: flatter
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

steps:
- name: GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
34 changes: 34 additions & 0 deletions .github/workflows/update-checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Update Checker

on:
schedule:
- cron: "0 6 * * *" # daily at 06:00 UTC
workflow_dispatch:

permissions:
contents: write
pull-requests: write

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
check:
name: Check com.visualstudio.code.yaml
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Check and update com.visualstudio.code.yaml
uses: docker://ghcr.io/flathub/flatpak-external-data-checker:latest
env:
GIT_AUTHOR_NAME: Flatpak External Data Checker
GIT_COMMITTER_NAME: Flatpak External Data Checker
# Sets commit author to github-actions[bot]
GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: --update --never-fork com.visualstudio.code.yaml
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
.DS_Store
.flatpak-builder/
*.deb
*.flatpak
*.key
*.swo
*.swp
*~
build-dir/
dist/repo
flatpak_app/
flatter-keyring/
node_modules
oci-bundle/
package-lock.json
private.key
repo/
Thumbs.db
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
MIT License

Copyright (c) 2026 François M.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

---

This license covers the packaging metadata in this repository only. Visual
Studio Code itself is proprietary software by Microsoft Corporation,
downloaded from Microsoft's servers at install time; see
https://code.visualstudio.com/license.
101 changes: 99 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,102 @@
# Visual Studio Code Flatpak<!-- omit in toc -->

🚨 Warning: This is an unofficial Flatpak build of Visual Studio Code, generated from the official Microsoft-built .deb packages [here](https://github.com/flathub/com.visualstudio.code/blob/master/com.visualstudio.code.yaml#L103).
🚨 Warning: This is an unofficial Flatpak build of Visual Studio Code, generated from the official Microsoft-built .deb packages [here](https://github.com/francoism90/com.visualstudio.code/blob/master/com.visualstudio.code.yaml#L103).

## Table of Contents<!-- omit in toc -->

- [Quick Start](#quick-start)
- [Build](#build)
- [Nested-sandbox install error](#nested-sandbox-install-error)
- [Signing](#signing)
- [Usage](#usage)
- [Execute commands in the host system.](#execute-commands-in-the-host-system)
- [Use host shell in the integrated terminal.](#use-host-shell-in-the-integrated-terminal)
- [Support for language extension.](#support-for-language-extension)
- [Support](#support)

## Quick Start

Add the remote repository:

```bash
flatpak remote-add --user --if-not-exists francoism90-vscode https://francoism90.github.io/com.visualstudio.code/index.flatpakrepo
```

Update the repository:

```bash
flatpak update
```

Install the app:

```bash
flatpak install francoism90-vscode com.visualstudio.code
```

> Note: the app will automatically update when you run `flatpak update`.

```bash
flatpak run com.visualstudio.code
```

### Build

It is possible to build the app yourself instead of using the prebuilt, signed
repo above.

```bash
git clone https://github.com/francoism90/com.visualstudio.code.git
cd com.visualstudio.code
./build.sh
flatpak run com.visualstudio.code
```

`build.sh` adds the Flathub remote (user), builds to a local repo, then
installs from that repo with the host's own `flatpak` binary (see
"Nested-sandbox install error" below for why it's split into two steps).

To build manually:

```bash
flatpak run org.flatpak.Builder --user --install-deps-from=flathub --force-clean --repo=repo \
build-dir com.visualstudio.code.yaml
flatpak --user remote-add --if-not-exists com.visualstudio.code-local ./repo --no-gpg-verify
flatpak --user install --noninteractive com.visualstudio.code-local com.visualstudio.code
```

#### Nested-sandbox install error

If `flatpak-builder` on your `$PATH` is itself a Flatpak (`org.flatpak.Builder`,
e.g. on immutable/hardened distros without a native package), running it with
`--install` directly can fail with:

```
bwrap: No permissions to create a new namespace, likely because the kernel
does not allow non-privileged user namespaces.
Error: Failed to install com.visualstudio.code: ...
```

That's `org.flatpak.Builder`'s own sandbox trying to nest another `bwrap`
sandbox for `flatpak install`, which some kernels/hardening policies block
regardless of user-namespace permissions otherwise being fine. Building to a
local repo and installing with the *host's* `flatpak` binary — as `build.sh`
and the manual steps above do — sidesteps it, since that install then only
needs one level of sandboxing, not two.

### Signing

The signed repo published to GitHub Pages by `.github/workflows/flatter.yml`
needs a GPG key in the `GPG_PRIVATE_KEY` (and optionally `GPG_PASSPHRASE`)
repo secrets. Generate one with:

```bash
bin/create-keys "Your Name" "you@example.com"
```

This prints the values to add as repo secrets. Delete `private.key` and the
`flatter-keyring/` directory afterwards — never commit them.

## Usage

Most functionality works out of the box, though please note that flatpak runs in an isolated environment and some work is necessary to enable those features.
Expand Down Expand Up @@ -89,10 +176,20 @@ $ flatpak install flathub org.freedesktop.Sdk.Extension.golang
$ FLATPAK_ENABLE_SDK_EXT=dotnet,golang flatpak run com.visualstudio.code
```

**Container support (Podman)**

To use Podman as a container runtime inside the sandbox (e.g. for Dev Containers), install the [`org.freedesktop.Sdk.Extension.podman`](https://github.com/francoism90/org.freedesktop.Sdk.Extension.podman) SDK extension from its own repo (not on Flathub — see that repo for why) and enable it the same way:

```
$ flatpak remote-add --if-not-exists francoism90-podman https://francoism90.github.io/org.freedesktop.Sdk.Extension.podman/index.flatpakrepo
$ flatpak install francoism90-podman org.freedesktop.Sdk.Extension.podman
$ FLATPAK_ENABLE_SDK_EXT=podman flatpak run com.visualstudio.code
```

**Finding other SDK**

`flatpak search <TEXT>`

## Support

Please open issues under: https://github.com/flathub/com.visualstudio.code/issues
Please open issues under: https://github.com/francoism90/com.visualstudio.code/issues
64 changes: 64 additions & 0 deletions bin/create-keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
# create-keys — generate a GPG signing key for your Flatpak repository and
# print the values you need to add as GitHub repository secrets.
#
# Usage: bin/create-keys [NAME] [EMAIL]
# NAME Human-readable key name (default: "Flatpak Repo")
# EMAIL Key email address (default: "flatpak@example.com")
#
# The private key is written to private.key and the keyring is stored in
# flatter-keyring/ (both in the current directory).
# Add private.key contents to the GPG_PRIVATE_KEY GitHub secret, then
# delete both private.key and the flatter-keyring/ directory.

set -euo pipefail

NAME="${1:-Flatpak Repo}"
EMAIL="${2:-flatpak@example.com}"
KEYHOME="./flatter-keyring"

# Create isolated GPG keyring directory
mkdir -p "$KEYHOME"
chmod 700 "$KEYHOME"

echo "Generating GPG key for '${NAME} <${EMAIL}>'..."

gpg --homedir "$KEYHOME" --batch --gen-key <<EOF
%no-protection
Key-Type: RSA
Key-Length: 4096
Name-Real: ${NAME}
Name-Email: ${EMAIL}
Expire-Date: 0
%commit
EOF

# Resolve the key ID from the email just created
KEY_ID=$(gpg --homedir "$KEYHOME" --list-secret-keys --keyid-format=long "${EMAIL}" \
| awk '/^sec/{split($2, a, "/"); print a[2]; exit}')

gpg --homedir "$KEYHOME" --armor --export-secret-key "${KEY_ID}" > private.key
FINGERPRINT=$(gpg --homedir "$KEYHOME" --with-colons --fingerprint "${KEY_ID}" | awk -F: '/^fpr:/ {print $10; exit}')

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " GitHub repository secrets"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo " GPG key id: ${KEY_ID}"
echo " GPG fingerprint: ${FINGERPRINT}"
echo ""
echo " Secret: GPG_PRIVATE_KEY"
echo " Value: use the full ASCII-armored private key below"
echo ""
cat private.key
echo ""
echo " Optional secret: GPG_PASSPHRASE"
echo " Value: only needed if your key is passphrase protected"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "⚠ Delete private.key and the keyring directory after uploading:"
echo " rm -f private.key && rm -rf \"$KEYHOME\""
echo " Never commit these files to the repository."
echo ""
Loading