Skip to content
Merged
4 changes: 3 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from "astro/config"
import { plainTextPlugin } from "@barnabask/astro-minisearch"
import { remarkReadingTime } from "./src/lib/remark-reading-time.mjs"
import downloadDdevRedirects from "./src/lib/download-ddev-redirects.js"
import prefetch from "@astrojs/prefetch"
import react from "@astrojs/react"
import rehypeAstroRelativeMarkdownLinks from "astro-rehype-relative-markdown-links"
Expand Down Expand Up @@ -30,7 +31,7 @@ export default defineConfig({
item.url.endsWith(".svg/") ||
item.url.endsWith(".xml/")
) {
// Dont index sitemaps or generated SVG, which come with `/` route endings here
// Don't index sitemaps or generated SVG, which come with `/` route endings here
return undefined
}
return item
Expand All @@ -42,6 +43,7 @@ export default defineConfig({
searchIndex({
output: "search.json",
}),
downloadDdevRedirects(),
prefetch(),
],
markdown: {
Expand Down
2 changes: 2 additions & 0 deletions public/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@
/author/heather /blog/author/heather-mcnamee 301
/author/rfay /blog/author/randy-fay 301
/author/rmanelius /blog/author/rick-manelius 301

# See src/lib/download-ddev-redirects.js for additional redirects
6 changes: 4 additions & 2 deletions src/components/CtaButton.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ export interface Props {
href: string
type?: string
target?: string
title?: string
}

const typeClasses = {
default: `border border-transparent text-white bg-blue-650 hover:bg-blue-800`,
hollow: `border border-blue-650 text-blue-650 hover:border-blue-800 hover:text-blue-800 dark:hover:text-blue-500 hover:border-blue-500`,
}

const { text, href, type = "default", target } = Astro.props
const { text, href, type = "default", target, title } = Astro.props
---

<a
href={href}
class={`flex items-center justify-center px-8 py-3 text-base font-bold rounded-md md:py-4 md:text-lg md:px-10 no-underline ` +
class={`flex items-center justify-center px-8 py-3 text-base font-bold rounded-md md:py-4 md:text-lg md:px-10 no-underline whitespace-pre-line ` +
typeClasses[type]}
target={target}
title={title}
role="button"
>
{text}
Expand Down
1 change: 1 addition & 0 deletions src/components/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const navigation = {
],
product: [
{ name: "About", href: "/about" },
{ name: "Download", href: "/download" },
{ name: "Swag Shop", href: STORE_URL, target: "_blank"},
{ name: "Contributing", href: "/support-ddev" },
{ name: "Contributor Live Training", href: "/blog/contributor-training"},
Expand Down
14 changes: 14 additions & 0 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ import SponsorsBanner from "./SponsorsBanner.astro"
rel="prefetch">Get Started</a
>
</li>
<li class="mx-4">
<a
class="font-bold whitespace-nowrap dark:text-white"
href="/download"
rel="prefetch">Download</a
>
</li>
<li class="mx-4">
<a
class="font-bold whitespace-nowrap dark:text-white"
Expand Down Expand Up @@ -135,6 +142,13 @@ import SponsorsBanner from "./SponsorsBanner.astro"
rel="prefetch">Get Started</a
>
</li>
<li>
<a
class="font-bold block py-3 px-4 text-lg border-t border-dotted"
href="/download"
rel="prefetch">Download</a
>
</li>
<li>
<a
class="font-bold block py-3 px-4 text-lg border-t border-dotted"
Expand Down
17 changes: 14 additions & 3 deletions src/components/quickstart/Windows.astro
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,24 @@ const { latestVersion } = Astro.props
Run the Installer
</h2>

<div class="not-prose mb-6">
<div class="not-prose mb-6 grid grid-cols-1 sm:grid-cols-2 gap-4 text-center">
<CtaButton
text="Download Windows Installer ↓"
href={`https://github.com/ddev/ddev/releases/download/${latestVersion}/ddev_windows_amd64_installer.${latestVersion}.exe`}
text="Download for AMD64 ↓\n(Intel/AMD)"
href="/download/ddev_windows_amd64_installer.exe"
title="For computers with Intel or AMD processors (most common)"
/>
<CtaButton
text="Download for ARM64 ↓\n(Snapdragon)"
href="/download/ddev_windows_arm64_installer.exe"
title="For computers with ARM processors like Qualcomm Snapdragon"
/>
</div>

<ul>
<li><strong>AMD64 (x86-64)</strong>: Most traditional Windows PCs (Intel/AMD processors)</li>
<li><strong>ARM64</strong>: Windows on ARM devices like Microsoft Surface Pro X, Surface Pro 9 (5G), or other ARM-based Windows devices</li>
</ul>

<p>Run the installer selecting the preferred "Docker CE" approach and selecting your "DDEV" distro. You can also find all releases at <a href="https://github.com/ddev/ddev/releases">DDEV Releases</a>.</p>

<p>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,14 @@ export async function getRepoDetails(name: string) {
}

/**
* Gets the most recent `ddev/ddev` tag name, like `v1.21.4`.
* Gets the most recent `ddev/ddev` tag name, like `v1.24.10`.
*
* @param stable Whether to return stable releases only (`true` by default).
* @returns tag name
*/
export async function getLatestReleaseVersion(stable = true) {
if (!githubTokenIsSet) {
return []
return "v1.24.9" // Fallback version for local development without token
}

let data = await getReleases()
Expand Down
123 changes: 123 additions & 0 deletions src/lib/download-ddev-redirects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import fs from "fs"
import path from "path"
import { getLatestReleaseVersion } from "./api.ts"
import { GITHUB_REPO } from "../const.js"

export default function downloadDdevRedirects() {
return {
name: "download-ddev-redirects",
hooks: {
"astro:build:done": async ({ dir }) => {
const rawVersion = await getLatestReleaseVersion() // e.g. "v1.24.10"
const version = rawVersion.replace(/^v/, "") // → "1.24.10"

const baseUrl = `https://github.com/${GITHUB_REPO}/releases/download/${rawVersion}`

const assets = [
// Checksums
{
path: "/download/checksums.txt",
file: "checksums.txt",
},

// Windows
{
path: "/download/ddev_windows_amd64_installer.exe",
file: `ddev_windows_amd64_installer.v${version}.exe`,
},
{
path: "/download/ddev_windows_arm64_installer.exe",
file: `ddev_windows_arm64_installer.v${version}.exe`,
},
{
path: "/download/ddev_windows-amd64.zip",
file: `ddev_windows-amd64.v${version}.zip`,
},
{
path: "/download/ddev_windows-arm64.zip",
file: `ddev_windows-arm64.v${version}.zip`,
},

// Linux - deb/rpm
{
path: "/download/ddev_linux_amd64.deb",
file: `ddev_${version}_linux_amd64.deb`,
},
{
path: "/download/ddev_linux_arm64.deb",
file: `ddev_${version}_linux_arm64.deb`,
},
{
path: "/download/ddev_linux_amd64.rpm",
file: `ddev_${version}_linux_amd64.rpm`,
},
{
path: "/download/ddev_linux_arm64.rpm",
file: `ddev_${version}_linux_arm64.rpm`,
},

// Linux - tar.gz
{
path: "/download/ddev_linux-amd64.tar.gz",
file: `ddev_linux-amd64.v${version}.tar.gz`,
},
{
path: "/download/ddev_linux-arm64.tar.gz",
file: `ddev_linux-arm64.v${version}.tar.gz`,
},

// Linux - WSL2
{
path: "/download/ddev-wsl2_linux_amd64.deb",
file: `ddev-wsl2_${version}_linux_amd64.deb`,
},
{
path: "/download/ddev-wsl2_linux_arm64.deb",
file: `ddev-wsl2_${version}_linux_arm64.deb`,
},
{
path: "/download/ddev-wsl2_linux_amd64.rpm",
file: `ddev-wsl2_${version}_linux_amd64.rpm`,
},
{
path: "/download/ddev-wsl2_linux_arm64.rpm",
file: `ddev-wsl2_${version}_linux_arm64.rpm`,
},

// macOS
{
path: "/download/ddev_macos-amd64.tar.gz",
file: `ddev_macos-amd64.v${version}.tar.gz`,
},
{
path: "/download/ddev_macos-arm64.tar.gz",
file: `ddev_macos-arm64.v${version}.tar.gz`,
},

// Shell completion scripts
{
path: "/download/ddev_shell_completion_scripts.tar.gz",
file: `ddev_shell_completion_scripts.v${version}.tar.gz`,
},
]

const redirectsPath = path.join(dir.pathname, "_redirects")
let redirectsContent = fs.readFileSync(redirectsPath, "utf8")

let downloadRedirects =
"\n\n# DDEV download redirects (generated at build time)"

for (const asset of assets) {
downloadRedirects += `\n${asset.path} ${baseUrl}/${asset.file} 302`
}

const finalContent = redirectsContent.trim() + downloadRedirects + "\n"
fs.writeFileSync(redirectsPath, finalContent)

console.log(
`[download-ddev-redirects] Generated ${assets.length} redirect(s) for version ${rawVersion}`
)
},
},
}
}
Loading
Loading